Suppose we have :
ImageView imageView_A = findViewById(R.id.imageview_dhze);
ImageView imageView_B = findViewById(R.id.imageview_dhhkjhkze);
ImageView imageView_C = findViewById(R.id.imageview_dhkhkjze);
ImageView imageView_D = findViewById(R.id.imageview_dhhuihuybze);
I want to make a function like this :
changeImages(String NAME) {
imageView_1_NAME.setImageResource(R.drawable.img);
imageView_2_NAME.setImageResource(R.drawable.img);
imageView_3_NAME.setImageResource(R.drawable.img);
}
And for example, I could use it like this :
changeImage("A");
to obtain :
imageView_1_A.setImageResource(R.drawable.img);
imageView_2_A.setImageResource(R.drawable.img);
imageView_3_A.setImageResource(R.drawable.img);
It is possible ? How can I do that ?
You could put all the ImageViews in a HashMap like this:
HashMap<String, ImageView> imageViews = new HashMap<>();
Then you add the ImageViews to the HashMap:
imageViews.put("A", imageView_A);
imageViews.put("B", imageView_B);
...
And your function could look like this then:
private void changeImage(String name) {
imageViews.get(name).setImageResource(R.drawable.img);
}
In this case you should only call changeImage() when the HashMap contains a key with the same value of String name. If you are not sure if a key exists you need to check if imageViews.containsKey(name) first.
You can do that:
void changeImage(String NAME) {
int imageId = this.getResources().getIdentifier("imageView_" + NAME, "id", this.getPackageName());
if (imageId != 0) {
ImageView imageView = (ImageView) findViewById(imageId);
imageView.setImageResource(R.drawable.img);
}
}
I think what you're looking for is something like this
fun changeImage(which: String) {
when(which) {
"a" -> imageView_A.setImageResource(R.drawable.img)
"b" -> imageView_B.setImageResource(R.drawable.img)
"c" -> imageView_C.setImageResource(R.drawable.img)
"d" -> imageView_D.setImageResource(R.drawable.img)
else -> throw IllegalArgumentException("Unknown image view")
}
}
int[] images = {R.id.imageA,R.id.imageB,R.id.imageC,R.id.imageD,R.id.imageE};
int[] drawables = {R.drawable.imageA,R.drawable.imageB,R.drawable.imageC,R.drawable.imageD,R.drawable.imageE};
for(int i=0;i<5;i++)
{
findViewById(images[i]).setImageResource(drawables[i]);
}
It's easier.
Related
I create app for Android on Kotlin,I need to create 55 variables to work with them in code,how to do it using a for loop?
Variables should be look like this:
val EditText0: EditText = findViewById(R. id.et0)
val EditText1: EditText = findViewById(R. id.et1)
and so on
You should use getIdentifier()
for(int i=0; i<some_value; i++) {
for(int j=0; j<some_other_value; j++) {
String buttonID = "btn" + i + "-" + j;
int resID = getResources().getIdentifier(buttonID, "id", getPackageName());
buttons[i][j] = ((Button) findViewById(resID));
buttons[i][j].setOnClickListener(this);
}
}
This is Java but same logic for kotlin.
When you have many of a similar kind of variable like this, you really should have a single List variable for all of them.
If they have consistent names like this, you can generate the IDs using resources.getIdentifier. It's easier using a List constructor than a for loop.
// In an Activity:
val myEditTexts: List<EditText> = List(55) { index ->
val id = resources.getIdentifier("et$index", "id", packageName)
findViewById<EditText>(id)
}
// In a Fragment's onViewCreated function:
val myEditTexts: List<EditText> = with(requireContext()) {
List(55) { index ->
val id = resources.getIdentifier("et$index", "id", packageName)
view.findViewById<EditText>(id)
}
}
If you don't want to keep all of them in a single list, then you should use View Binding to let the properties be generated for you.
I have a JSON sample list as below and I tried to put this into my spinner:-
[{"occupation_id":0,"occupation_name":"Teacher"},{"occupation_id":1,"occupation_name":"Business Owner"}]
When I tried to apply these code:-
val jsonArray = JSONArray(jsonString)
var list = ArrayList<Occupation>()
var x = 0
while (x < jsonArray.length()) {
var jsonObject = jsonArray.getJSONObject(x)
list.add(Occupation(
jsonObject.getString("occupation_id"),
jsonObject.getString("occupation_name")
))
x++
}
var spinnerOccupation = findViewById<Spinner>(jasiez.helloworld.jasiez.R.id.spinnerOccupation)
// Initializing an ArrayAdapter
val occupationAdapter = ArrayAdapter(
this, // Context
android.R.layout.simple_spinner_item,
list// Array
)
occupationAdapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line)
spinnerOccupation.adapter = occupationAdapter
I getting this in my spinner
When I tried to change
val occupationAdapter = ArrayAdapter(
this, // Context
android.R.layout.simple_spinner_item,
list// Array
)
to
val occupationAdapter = ArrayAdapter(
this, // Context
android.R.layout.simple_spinner_item,
list.occupation_name.toList()
)
I getting error Unresolved reference: occupation_name. If I change to list[0].occupation_name.toList() I will show 1st occupation name with 1 char in every single dropdown list option.
How can I get proper occupation name in each option here? Please help.Thank you.
When you are using ArrayAdapter, you can only pass the list of String (List), You can't pass like List so make the list like below:
var list = ArrayList<String>()
.......
list.add(jsonObject.getString("occupation_name"))
I have also encountered the same when dealing with JSon. What I did is I override toString from my Object. In your case, you can override a toString to your occupation name from your Occupations Object.
public class Occupation {
int occupation_id;
String occupation_name;
public Occupation() {
}
public int getOccupation_id() {
return occupation_id;
}
public void setOccupation_id(int occupation_id) {
this.occupation_id = occupation_id;
}
public String getOccupation_name() {
return occupation_name;
}
public void setOccupation_name(String occupation_name) {
this.occupation_name = occupation_name;
}
//converts your occupation_name to string
#NonNull
#Override
public String toString() {
return occupation_name;
//or you can also add title to your occupation name by doing this
//return "Occupation: "+ occupation_name;
}
}
Check out if this works for you.
You can write a custom adapter to hold your data list, and override getview to set the values in spinner's textview. Have a look at this link to see an example.
I try access to drawable resource that I put in hashmap object
this is my relevant code:
private void pairImagesCollection() {
mImages.put(R.drawable.img1, R.drawable.img1shadow);
mImages.put(R.drawable.img2, R.drawable.img2shadow);
mImages.put(R.drawable.img3, R.drawable.img3shadow);
mImages.put(R.drawable.img4, R.drawable.img4shadow);
}
private void checkMatch(View dragView, View view) {
ImageView target = (ImageView) view;
ImageView dragged = (ImageView) dragView;
Drawable image = dragged.getDrawable();
int imgId = mImages.get(Integer.valueOf(image)); // wrong, I don't know how to do it ?!
target.setImageResource(imgId);
}
Any help will be appraised!
You can use Iterator
Iterator itObj = hashMapOBJ.entrySet().iterator();
while (itObj .hasNext()) {
Map.Entry pair = (Map.Entry) itObj.next();
String Key = (String) pair.getKey();
Drawable Value = (Drawable) pair.getValue();
hashMapOBJ.put(Key, Value);
System.out.println("Key: " + Key + "------>" + Value);
}
int imgId = mImages.get(Integer.valueOf(image));
You cannot get Resource/Drawable Id from ImageView through Drawable. With codes above, You can set tag for ImageView dragged. After that get value with with your mImages.
Before you checkMatch, you set tag for dragView as Drawble, something like that:
dragged.setTag(R.drawable.img1);
And now you can getDrawableId and
imgId = getDrawableId(dragged);
private int getDrawableId(ImageView iv) {
return (Integer) iv.getTag();
}
You got a hashmap that stores references to an image and its shadow right?
Which image you want to put on the image view? You have to iterate through your map and put the image you want:
Iterator iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry pair = (Map.Entry)iterator.next();
System.out.println(pair.getKey() + " = " + pair.getValue());
}
If you want to put the value image then you put the pair.getKey() else you put the pair.getValue().
target.setImageResource(R.drawable.xxx);
I have over 100 images in my drawable. Its basically a Category. I am calling data from server where a column included category. My images were named as cat_image1, cat_image2, cat_image3 etc. The server sending the corresponding srting as Image1, Image2, Image3 etc respectively. I think its not the way what I am doing
String catString = someJSONObject.getString(Config.POI_CATEGORY);
if (catString == "image1") {
someView.setImage(getResources().getDrawable(R.mipmap.image1));
}
else if (catString == "image2") {
someView.setImage(getResources().getDrawable(R.mipmap.image2));
}
else if (catString == "image3") {
someView.setImage(getResources().getDrawable(R.mipmap.image3));
}
...
...
...
Try something like this:
// catString = cat -> R.drawable.cat
int imageId = getResources().getIdentifier(catString, "drawable", getPackageName());
someView.setImage(imageId));
If you need a prefix use this:
// catString = cat -> R.drawable.ic_cat
int imageId = getResources().getIdentifier("ic_" + catString, "drawable", getPackageName());
someView.setImage(imageId));
You can also use a HashMap:
HashMap<String, Integer> hm = new HashMap<>();
// Put elements to the map
hm.put("cat", R.drawable.ic_some_cat_image);
hm.put("other cat", R.drawable.ic_other_cat);
for (int i = 0; i < typeofplace.length; i++) {
// You might want to check if it exists in the hasmap
someView.setImage(hm.get(catString));
}
Searched and working on this a long while - no luck. ( It must be simple ? Thanks for the assist. )
Trying to get / set a screen full of EditTexts' text, but not with the usual, more hard-coded way:
... findViewById (R.id.SomeTextWidgetId) ;
Instead, I'm trying to figure out a reusable way via a variable holding the (String) name_of_widget.
In psuedo code:
findViewById (R.id.>> StringVarHere << ); // how to do that ?
I tried also this findViewById method, but it didn't work (!?)
//// given:
static final String FIELD_TV_FEE = "TextViewFee" ;
static final String FIELD_TV_FOO = "TextViewFoo" ;
static final String FIELD_TV_FUM = "TextViewFum" ;
//// and some arbitrary number more of similar fields
static final String [] ALL_FIELDS = {
FIELD_TV_FEE ,
FIELD_TV_FOO ,
FIELD_TV_FUM // ...
} ;
//// ...
//// this part works
int ResourceID;
String stringVarHere = FIELD_TV_FEE;
//// outputs a correct id, say '0x7f05000f' as in R.id.xxx below
ResourceID = context
.getResources()
.getIdentifier ( stringVarHere,
"id",
context
.getApplicationInfo()
.packageName
) ;
Log.d ("MyClass" , "RESID = " + Integer.toHexString(ResourceID) ) ;
/*
* that's where I'm stuck ^^^ ... how do I do:
*/
String field_name ;
for ( field_name : ALL_FIELDS ) {
(EditText) SomethingLike_a_findViewById(field_name).setText ("Hello Wurld") ;
}
I've tried .setId ...
//// details
<!-- excerpt from working xml layout -->
<EditText
android:id="#+id/TextViewFee"
android:inputType="text"
android:layout ... etc ...
/>
<EditText
android:id="#+id/TextViewFoo"
android:inputType="text"
android:layout ... etc ...
/>
<EditText
android:id="#+id/TextViewFum"
android:inputType="text"
android:layout ... etc ...
/>
As expected, the gen'ed R file has something like this:
// ...
public static final class id {
public static final int TextViewFee=0x7f05000f;
public static final int TextViewFum=0x7f05001c;
public static final int TextViewFoo=0x7f05001d;
// ... etc
Yes, thanks - it makes sense to do it in the activity. I was trying to keep it from getting too code bulky. Here's what I'm doing now, based on your and A-C's helpful suggestions. The intention is to get all the text of fields of a form back in one String[]. (I know I could brute force all the fields too.)
What do you all think about this below - seems very similar to your suggestion, madlymad ? I am wondering if this is a poor design approach ?
public class FoodBar {
private Activity activity;
private Context ctx;
public FoodBar ( Activity _activity ) {
this.activity = _activity;
this.ctx = this.activity.getApplicationContext() ;
}
public String[] getTextFromAllEditTexts () { // the UI views
int res_id = 0;
int i = 0;
String [] retValues = new String [MyClassName.ALL_FIELDS_LENGTH] ;
for (String field : MyClassName.ALL_FIELDS_ALL_VEHICLES) {
res_id = this.ctx.getResources()
.getIdentifier ( field, "id", this.ctx.getPackageName() );
((EditText) this.activity
.findViewById (res_id))
.setText( "Meat and Potatoes" ) ;
// redundant - get it right back to make sure it really went in !
retVal[i++] = ((EditText) this.activity
.findViewById (res_id))
.getText().toString() ;
}
return retVal;
} // end func
} // end class
Then from the Activity class, it's just:
String [] theFields = null;
FoodBar = new FoodBar (this);
try {
theFields = FoodBar.getTextFromAllEditTexts ();
} catch (Exception e) {
Log.d ("OOPS", "There's a big mess in the Foodbar: " + e.toString() );
}
The way you could do it is (as I understand the way you are trying):
This can be in non-Activity (YourClassname.java):
public static int getMyId(Context context, String field) {
return context.getResources().getIdentifier (field, "id", context.getPackageName());
}
in Activity-class:
for ( String field_name : YourClassname.ALL_FIELDS ) {
int resid = YourClassname.getMyId(context, field_name);
if(resid != 0) { // 0 = not found
EditText et = (EditText) findViewById(resid);
if (et != null) {
et .setText ("Hello Wurld") ;
}
}
}
But I think it's better to code in the activity class like:
String packageName = getPackageName();
Resources res = getResources();
for ( String field_name : YourClassname.ALL_FIELDS ) {
int resid = res.getIdentifier (field_name, "id", packageName);
if(resid != 0) {// 0 = not found
EditText et = (EditText) findViewById(resid);
if (et != null) {
et .setText ("Hello Wurld") ;
}
}
}
A-C suggested something along the lines of:
res_id = getResources().getIdentifier (field, "id", getPackageName());
((EditText)findViewById (res_id)).setText("NoLongerFubar");
this DOES work - when I tried it standalone in a test rig. Thanks ! Still not sure what was blowing up, but I suspect it was Context or Resource items not being accessible.
Note that variable names (such as R.id.some_id) are only available at compile time and cannot be accessed from a String value at run time. Since these ids are declared as ints, you might consider using an int[] or List<Integer> to store the ids. Depending on how dynamic your layout is and what you are doing with the Views in it, you might even want to simply create the Views at run time and store an array or List of them without using any ids at all.