Easy way to rewrite in a loop - java

Is there an easier way to write this code to make my image views invisible? I was hoping I could use some type of for loop. I am also new to programming so in your answer, can you please explain how the loop is working so I can use it in future references? Also, how do I assign 15 image views to 1 array?
iv_1.setVisibility(View.INVISIBLE);
iv_2.setVisibility(View.INVISIBLE);
iv_3.setVisibility(View.INVISIBLE);
iv_4.setVisibility(View.INVISIBLE);
iv_5.setVisibility(View.INVISIBLE);
iv_6.setVisibility(View.INVISIBLE);
iv_7.setVisibility(View.INVISIBLE);
iv_8.setVisibility(View.INVISIBLE);
iv_9.setVisibility(View.INVISIBLE);
iv_10.setVisibility(View.INVISIBLE);
iv_11.setVisibility(View.INVISIBLE);
iv_12.setVisibility(View.INVISIBLE);
iv_13.setVisibility(View.INVISIBLE);
iv_14.setVisibility(View.INVISIBLE);
iv_15.setVisibility(View.INVISIBLE);
iv_16.setVisibility(View.INVISIBLE);
iv_17.setVisibility(View.INVISIBLE);
iv_18.setVisibility(View.INVISIBLE);
iv_19.setVisibility(View.INVISIBLE);
iv_20.setVisibility(View.INVISIBLE);
iv_21.setVisibility(View.INVISIBLE);
iv_22.setVisibility(View.INVISIBLE);
iv_23.setVisibility(View.INVISIBLE);
iv_24.setVisibility(View.INVISIBLE);
iv_25.setVisibility(View.INVISIBLE);
iv_26.setVisibility(View.INVISIBLE);
iv_27.setVisibility(View.INVISIBLE);
iv_28.setVisibility(View.INVISIBLE);
iv_29.setVisibility(View.INVISIBLE);
iv_30.setVisibility(View.INVISIBLE);
iv_31.setVisibility(View.INVISIBLE);
iv_32.setVisibility(View.INVISIBLE);
iv_33.setVisibility(View.INVISIBLE);
iv_34.setVisibility(View.INVISIBLE);
iv_35.setVisibility(View.INVISIBLE);
iv_36.setVisibility(View.INVISIBLE);
iv_37.setVisibility(View.INVISIBLE);
iv_38.setVisibility(View.INVISIBLE);
iv_39.setVisibility(View.INVISIBLE);
iv_40.setVisibility(View.INVISIBLE);
iv_41.setVisibility(View.INVISIBLE);
iv_42.setVisibility(View.INVISIBLE);
iv_43.setVisibility(View.INVISIBLE);
iv_44.setVisibility(View.INVISIBLE);
iv_45.setVisibility(View.INVISIBLE);
iv_46.setVisibility(View.INVISIBLE);
iv_47.setVisibility(View.INVISIBLE);
iv_48.setVisibility(View.INVISIBLE);
iv_49.setVisibility(View.INVISIBLE);
iv_50.setVisibility(View.INVISIBLE);
iv_51.setVisibility(View.INVISIBLE);
iv_52.setVisibility(View.INVISIBLE);
iv_53.setVisibility(View.INVISIBLE);
iv_54.setVisibility(View.INVISIBLE);
iv_55.setVisibility(View.INVISIBLE);
iv_56.setVisibility(View.INVISIBLE);
iv_57.setVisibility(View.INVISIBLE);
iv_58.setVisibility(View.INVISIBLE);
iv_59.setVisibility(View.INVISIBLE);
iv_60.setVisibility(View.INVISIBLE);

Put your iv_xx objects in a list or array, then use a loop to iterate through the array:
ArrayList<IVType> ivList = new ArrayList<>();
// use ivList.add() to add each object to the list.
for (IVType iv: ivList)
{
iv.setVisibility(View.INVISIBLE);
}

First create a array of size N of type img(Your object).
N—> will be the number of images.
img[] a=new img[N];
Here, we are creating a array of type img with size N.
Now you need to add all your 50 image object to this array using for loop
Then loop through the array and set the property like below.
for(int i =0; i<N;i++){
a[i].setVisibilty(View.INVISIBLE);
}

Let's assume this is your POJO
public class ImageView {
private View visibility;
public ImageView(View view) {
visibility = view;
}
public View getVisibility() {
return visibility;
}
public void setVisibility(View visibility) {
this.visibility = visibility;
}
enum View {
VISIBLE, INVISIBLE
}
}
Also, consider the scenario that you have already ImageView list that contains 60 image instances.
List<ImageView> imageViews = new ArrayList<>();
//instead of creating 60 beans separately and adding it to list you can just follow the below code
IntStream.range(0, 60).forEach(e -> {
imageViews.add(new ImageView(ImageView.View.INVISIBLE));
});
//you can manipulate the ImageView instances as below
//imageViews.forEach(e -> e.setVisibility(ImageView.View.INVISIBLE));
//As per the requirement you can convert the list into array as below. There is no need to mention the pre-sized array (new ImageView[imageViews.size()]) here
ImageView[] imageViewsArr = imageViews.toArray(new ImageView[0]);
//If you want to make a arrays of first 15 instances then you can limit the size to 15 (your question mentioned just 15 imageViews to 1 array)
//ImageView[] imageViewsArr = imageViews.stream().limit(15).toArray(new ImageView[0]);

Related

I have an arrayList outside of an onClick method that refers to the arrayList, but it is giving me errors

I have an arrayList outside of an onClick() method. I am referring to some elements in the arrayList in my onClick() class. But when I type the name of the ArrayList and the list, it highlights in red. Both of the classes are public though.
I have tried putting the code of the arryalist and the list randomization process, but the it re randomizes every time I click something.
The part that is giving me errors is in the first case in the switch case statement, where I try to get the first position in the allImages arraylist, and the first position in the imageList List. They are in the onclick class. The arrayList and List are outside of that class.
I cannot put the arrayList and List inside of the class, because that will re randomize every time I click something. (I am trying to make a matching game)
Here is the code:
public void Random() {
Integer[] allImages = { R.drawable.cheetah, R.drawable.cheetah, R.drawable.chick, R.drawable.chick, R.drawable.fox,
R.drawable.fox, R.drawable.giraffe, R.drawable.giraffe, R.drawable.owl,
R.drawable.owl, R.drawable.panda, R.drawable.panda, R.drawable.sheep, R.drawable.sheep, R.drawable.tiger,
R.drawable.tiger};
List<Integer> imageList = Arrays.asList(allImages);
Collections.shuffle(imageList);
imageList.toArray(allImages);
}
public void onClick(View v) {
final int id = v.getId();
if (maxCounter < 2) {
switch (id) {
case R.id.one:
one.setBackgroundResource(allImages[0]); THE ALL IMAGES PART HIGHLIGHTS IN RED
unmatchedImages[maxCounter] = R.id.one;
unmatchedImages[maxCounter++] = imageList.get(0); ALSO IMAGE LIST HIGHLIGHTS IN RED
break;
//After this, i have cases for each button
}
}
else {
one.setBackgroundResource(R.drawable.qmarks);
//After this, i have a setBackgroundResource for each button
}
}
Please help. Any help is greatly appreciated.
Is your Random() should be method or class?
Base on name, which starts from uppercase (Random) it look like class.
But you added public void before name, so it's method.
I think you can move your Random() method (!) content to your Activity. Are you planning to set in Fragment or Activity?
Steps to do:
1) Move your list as field in your Activity (or fragment - I don't know what you have)
2) Shuffle list in onCreate() (or in different place but before first usage)
// 0 - Use it in your class.
// This "MainActivity" is only for example - use your name!
public class MainActivity extends AppCompatActivity {
// 1 - List of items
List<Integer> allImages = {R.drawable.cheetah, R.drawable.cheetah, R.drawable.chick,
R.drawable.chick, R.drawable.fox, R.drawable.fox, R.drawable.giraffe,
R.drawable.giraffe, R.drawable.owl, R.drawable.owl, R.drawable.panda,
R.drawable.panda, R.drawable.sheep, R.drawable.sheep, R.drawable.tiger,
R.drawable.tiger};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 2 - Shuffle them
Collections.shuffle(imageList);
}
.
.
.
}
The problem I see is that yes Random is public but in the OnClick() method your are trying to access a property of Random without telling who is the parent.
So instead of just using allImages and imageList.get() use Random().allImages and Random().imageList.get() Hope this helps.

Sub arraylist output repeating itself after n elements

Newbie. I'm coding a quiz app full code on Github that loads an arrayList with four arguments:
question
image (from drawables)
key answer
possible answers presented in a radioGroup (sub-arrayList)
from the strings.xml as below
...
<string name="questionOne">Who is the "Modern Love" rock star singer?</string>
<string name="answerOne">David Bowie</string>
<string-array name="celebrityOne">
<item>Jaimie Hendrix</item>
<item>David Bowie</item>
<item>Jim Morrison</item>
<item>Elvis Presley</item>
</string-array>
...
Below is how the arguments are loaded in MainActivity (The third argument is a sub-arraylist)
ArrayList<Object> arrayList = new ArrayList<>();
loaddata()
...
public void loadData() {
arrayList.add(new Quiz(getResources().getString(R.string.questionOne),
getResources().getDrawable(R.drawable.celebrity_one_image, null),
new ArrayList<>(Arrays.asList(getResources().getStringArray(R.array.celebrityOne))),
getResources().getString(R.string.answerOne)));
arrayList.add(new Quiz(getResources().getString(R.string.questionTwo),
getResources().getDrawable(R.drawable.celebrity_two_image, null),
new ArrayList<>(Arrays.asList(getResources().getStringArray(R.array.celebrityTwo))),
getResources().getString(R.string.answerTwo)));
...
}
The issue is after N iterations, the sub-arrayList starts repeating itself (See image below).
Also I think maybe the source of the problem is in the Adapter, where for each string in sub-array is assigned to a radioButton;
void createRadioButtons(String[] arrayAnswer) {
if (mRadioGroup.getChildAt(0) != null)
return;
for (int i = 0; i < arrayAnswer.length; i++) {
mRadioGroup.addView(createRadioButtonAnswerAndSetOnClickListener(arrayAnswer[i]));
}
}
RadioButton createRadioButtonAnswerAndSetOnClickListener(String string) {
RadioButton radioButton = new RadioButton(mContext);
radioButton.setText(string);
radioButton.setOnClickListener(this);
return radioButton;
}
My situation might be similar to this but I have no static fields and arrayList is initialized as new so no need to clear().
From Documentation:
The RecyclerView creates only as many view holders as are needed to display the on-screen portion of the dynamic content, plus a few extra. As the user scrolls through the list, the RecyclerView takes the off-screen views and rebinds them to the data which is scrolling onto the screen.
This means RecyclerView reuses already created view holders when you are scrolling it(that is why your data repeats), and you must repopulate views with new data. So, instead of returning from createRadioButtons method, when mRadioGroup.getChildAt(0) != null, you must change RadioButtons texts to your new data from arrayAnswer.
in your adapter just change this:
if (mRadioGroup.getChildAt(0) != null)
return;
To this:
if (mRadioGroup.getChildAt(0) != null)
mRadioGroup.removeAllViews();
At some moment your adapter, began to reuse view holders which were created at the top of the recyclerView, but it was already filled with data, so when you call return, you just leave your old data, while you need to delete it and then add new data...

Editing duplicated item in RecyclerView with EditText

I have a list of elements that is editable: I can add/delete new elements to the list. Furthermore I can duplicate each Element - duplicated elements are appended to the end of the list. Each element is displayed with a corresponding EditText where users can input quantity of the given element. The Problem: After duplicating an Element E1, editing the quantity of E1 also changes quantity of E2.
Every ListItem looks like this:
TextView(ElementTitle) / EditText(ElementQuantity)
Everything works flawlessly on lists of many elements - until I use my "duplicate" function.
I assume that the problem has something to do with the Recyclerview reusing the EditTextListeners. I am assigning these in onCreateViewHolder as described in this answer: https://stackoverflow.com/a/31860393/6551120.
I tried adding notifydatasetchanged() wherever I could imagine any value. In duplicatedSelected() I tried unregistering and clearing adapter and LayoutManager and creating a new Adapter - without any result.
This is the method that duplicates my elements (In ListActivity):
private void duplicateSelected(){
List selectedItemPositions = mAdapter.getSelectedItems();
for (int i = 0; i < selectedItemPositions.size(); i++) {
int j =(int) selectedItemPositions.get(i);
modulElements.add(modulElements.get(j));
}
mAdapter.notifyDataSetChanged();
In MyAdapter:
private class ModulElementEditTextListener implements TextWatcher {
private int position;
public void updatePosition(int position) {
this.position = position;
}
//Other Override Methods cut out for simplicity
#Override
public void afterTextChanged(Editable editable) {
updatePosition(position);
int timesMultiplied;
if(editable.toString().equals("")){
timesMultiplied=Integer.parseInt("0");
}else{
timesMultiplied = Integer.parseInt(editable.toString());
}
modulElements.get(position)
.setMultiplier(newModulElementMultiplier());
modulElements.get(position)
.getMultiplier().setTimesMultiplied(timesMultiplied);
}
}
Expected result when entering quantity for E1: Quantity for E1 changes
Actual result when entering quantity for E1: Quantity for E1 and E2 (And E3, E4,E5... when I duplicate multiple times) changes.
If I save the list of elements to a database and reopen it I can flawlessy edit quantity of E1 and it does NOT change quantity of E2 - as I would expect it to happen in the first case.
Every hint or idea welcome, thank you so much!
You must implement the cloneable interface for your data model and modify this line
modulElements.add(modulElements.get(j).clone());
Now you have different objects in the list

Removed Images from ArrayList are still showing

I am working on a 2D game in which sprites for player are stored in array list. Since player has multiple states, I want to remove previous states upon use. I have an ArrayList as:
List<Image> x = new ArrayList();
Now I use images from this list as: someImageView.setImage(x.getImage(y));
And I remove first (say 5: 0,1,2,3,4,5th images) states as:
for(int i = 0; i < 6; i++)
x.remove(y);
But these images still show instead of the next image set.
Could it be some sort of Caching? If so how can I delete this cache so my new images are applied?
My sprite images declaration is as follows (shown for one image, but its similar for all images):
Image someImg = new Image("path", true, false, true);
I don't know whether I understand you properly.
So, you use e.g. the first element of a list to be set on an ImageView (it is set properly), then you remove this element from the list.
At this point do you expect that the image will be removed from the ImageView also?
Why is shall be removed?
The list contains references to objects (pointers). When you set an image from the list the reference is passed to the ImageView, so now it will also point to that object. If you remove the reference from the list, it does not matter, the ImageView will still point to that reference.
So you can call setImage explicitly after you removed the elements, or use an ObservableList and set the image on remove (something like this):
ObservableList<Image> iList = FXCollections.observableArrayList();
iList.addListener(new ListChangeListener<Image>()
{
#Override
public void onChanged(javafx.collections.ListChangeListener.Change<? extends Image> change) {
while(change.next())
{
if(change.wasRemoved())
imgView.setImage(iList.get(0));
}
});
}

Save arraylist values in a function

So I was trying to get the number of samples but everytime I call this function the available sample list resets due to ArrayList<Sample> available = new ArrayList<Sample>(this.getSample()); So if I call another function that remove or add the sample then call this function it will always be the default plus or minus the size. For example....if this.getSample() size is 5 and there are 2 soils that aren't available. I call the remove function twice but my result will always end with 4 where it should be 3.
public ArrayList<Sample> getAvailableSample() {
ArrayList<Sample> available = new ArrayList<Sample>(this.getSample());
//create a copy of arraylist from sample. (doesn't mess with original data)
for(Sample s : available) { //loop through list
if(s.getSoil()!=null){ //soil is not available
available.remove(s); //remove from list
}
}
//System.out.println("size of available: "+available.size());
return available; //returns number of available samples
}
I could not move the ArrayList<Sample> available = new ArrayList<Sample>(this.getSample()); outside because ArrayList<Sample>(this.getSample()); default is null and I cannot call this class's function without messing up other functions in this or other classes.
Any idea would be appreciated.
You are looping on s, but reading only b.
for(Sample s : available) {
if(s.getSoil()!=null) { // s, not b.
available.remove(s); // s, not b.
}
}
You can read your loop like for each Sample s in available.
Create a Collection c, and then remove it after your loop.
List<Sample> c = new ArrayList<>();
for(Sample s : available) {
if(s.getSoil()!=null) {
c.add(s);
}
}
available.removeAll(c);
Im thinking that the problem is that you cant delete an object that from a list that is being interated.
Can you try doing as below? Instead deleting the Sample that don`t have available soil you can create a new list with only the objects that have soil.
public ArrayList<Sample> getAvailableSample() {
ArrayList<Sample> available = new ArrayList<Sample>();
for(Sample s : this.getSample()) { //loop through list
if(s.getSoil()==null){ //soil is available
available.add(s); //add into the available list
}
}
//System.out.println("size of available: "+available.size());
return available; //returns number of available samples
}

Categories

Resources