the app keep crashing whenever the While loop starts - java

I have made an ArrayList store the numbers from 1 to 10 in Strings, then I wanted to make the numbers in the ArrayList displayed in the screen using While loop. But the app keeps crashing when the loop starts.`
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_number);
}
ArrayList<String> words = new ArrayList<>();
{
// Create an ArrayList of words
words.add("One");
words.add("Two");
words.add("Three");
words.add("Four");
words.add("Five");
words.add("Six");
words.add("Seven");
words.add("Eight");
words.add("Nine");
words.add("Ten");
LinearLayout rootView = findViewById(R.id.rootView);
// Create a variable to keep track of the current index position
int index = 0;
// Keep looping until we've reached the end of the list (which means keep looping
// as long as the current index position is less than the length of the list)
while (index < words.size()) {
// Create a new TextView
TextView wordView = new TextView(this);
// Set the text to be word at the current index
wordView.setText(words.get(index));
// Add this TextView as another child to the root view of this layout
rootView.addView(wordView);
// Increment the index variable by 1
index++;
}
}

The initialisation is called before the onCreate method. so the views are not created yet.
ArrayList<String> words = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_number);
// Create an ArrayList of words
words.add("One");
words.add("Two");
words.add("Three");
words.add("Four");
words.add("Five");
words.add("Six");
words.add("Seven");
words.add("Eight");
words.add("Nine");
words.add("Ten");
LinearLayout rootView = findViewById(R.id.rootView);
// Create a variable to keep track of the current index position
int index = 0;
// Keep looping until we've reached the end of the list (which means keep looping
// as long as the current index position is less than the length of the list)
while (index < words.size()) {
// Create a new TextView
TextView wordView = new TextView(this);
// Set the text to be word at the current index
wordView.setText(words.get(index));
// Add this TextView as another child to the root view of this layout
rootView.addView(wordView);
// Increment the index variable by 1
index++;
}
}

You are writing this code outside your onCreate function. Put all the code from Array List to index++ inside onCreate function, so when activity is created, it is inside the content.

Related

'The specified child already has a parent. You must call removeView() on the child's parent first.' and not sure where I'm wrong

This is my code excerpt for the Numbers Activity:
Note: 'words' is an 'ArrayList' of type String with elemts ranging from 'One-Ten' with 'size=9'.
// Find the root view of the Numbers activity
LinearLayout rootViewNumbers = findViewById(R.id.root_numbers_LL);
// creating a text view to assign the words to it
TextView wordView = new TextView(this);
for(int i = 0; i <= words.size(); i++) {
// setting the text to text view by using the 'i' for index position iterator
wordView.setText(words.get(i));
// setting the text view to the root view
rootViewNumbers.addView(wordView);
}
When I run the app I'm getting the error as
'The specified child already has a parent. You must call removeView()
on the child's parent first.'
My understanding is that we have declared a text view and now we are iterating through loop to add elements of 'words' ArrayList and adding the text view to the root view. Please help me where am I going wrong!!
If you declare the TextView inside the for loop, you will be adding a new view instance to rootViewNumbers each iteration, whilst your code tries to add the same view instance to the parent which throws the exception.
You may edit your code to be:
TextView wordView;
for(int i = 0; i <= words.size(); i++) {
wordView = new TextView(this)
// setting the text to text view by using the 'i' for index position iterator
wordView.setText(words.get(i));
// setting the text view to the root view
rootViewNumbers.addView(wordView);
}

Android Studio TextViews onClick all perform the same action, how do I fix it?

I have this function which is supposed to create an array of TextViews with unique ids.
Each TextView is supposed to perform a unique action, however when any one of them is clicked, they perform the function of the last TextView .
(ie, anyone of them appends a 9 to the last TextView the way this i set up) Do you know why it does this, and how I can fix it?
Any help would be greatly appreciated.
//Code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_what_can_imake);
int textViewCount = 10;
TextView[] textViewArray = new TextView[textViewCount];
RelativeLayout myLayout = (RelativeLayout) findViewById(R.id.myLayout);
for(int i = 0; i < textViewCount; i++) {
textViewArray[i] = new TextView(this);
textViewArray[i].setText("Title"+Integer.toString(i));
textViewArray[i].setPadding(8,8+50*i,8,0);
textViewArray[i].setId(i);
LayoutParams myTitleDimensions = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
textViewArray[i].setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
int myId = v.getId();
((TextView) v).append(Integer.toString(myId));
}
});
myLayout.addView(textViewArray[i],myTitleDimensions);
}
}
You are using different paddingTop to layout your TextViews vertically:
textViewArray[i].setPadding(8,8+50*i,8,0);
this makes the TextViews visually separate to each other, but in fact they are all overlapped, the 2nd one overlapped the 1st, the 3rd one overlapped the 2nd, etc. At last, the 9th one overlapped all, so no matter which text you clicked, you actually clicked the 9th one.
To fix this, you should change the way you layout the TextViews.
For example, use RelativeLayout.addRule(int verb, int anchor):
RelativeLayout.LayoutParams myTitleDimensions = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
if (i > 0) {
myTitleDimensions.addRule(RelativeLayout.BELOW, i - 1);
}
By the way, 0 is not a valid id, so your 1st TextView will be still overlapped by the 2nd one, just change the way to generate ids a little.

listview move up item position

I'm trying to move the item's position on ListView by pressing a button which will move up one row of the list.I tried looking for other answers on SO but their ListView was populated from an ArrayList whilst mine from fileList()
Do I need to somehow sort the files in fileList()? or is using ArrayList enough for me to change their positions?
I used ArrayList to get the item's position
How I populate my ListView
String[] SavedFiles;
String dataDr;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_address);
dataDr = getApplicationInfo().dataDir;
showDirFile(dataDr);
}
void showDirFile(String dirpth)
{
String path = dirpth+"/files";
Log.d("Files", "Path: " + path);
File f = new File(path);
File file[] = f.listFiles();
Log.d("Files", "Size: "+ file.length);
SavedFiles = new String[file.length];
for (int i=0; i < file.length; i++)
{
Log.d("Files", "FileName:" + file[i].getName());
SavedFiles[i] = file[i].getName();
}
ArrayAdapter<String> adapter
= new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
SavedFiles);
listView.setAdapter(adapter);
}
How I get the item's position
OnItemClickListener getFileEditContent = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Get item's file name according to position
String clickedFile = (String)parent.getItemAtPosition(position);
stringArrayList.add(clickedFile)
// Get item position
intArrayList.add(position);
}
};
you have used String[] SavedFiles; for showing list using adapter.
On click of an Item you want to move it up for that write logic for swapping array items and notify adapter.
Your logic will make the top item to current one and current one to top one.
Hope this will help you.
I managed to solve it myself by using the Collections.swap method
Example
Collections collections;
void positionChange(){
//to store arrays into ArrayList
List<String> newList = new ArrayList<String>(Arrays.asList(myDataFiles));
//to get the item's position # get the first item in array if multiple arrays exist
String currentPos = String.valueOf(intArrayList.get(0));
int oldPos = Integer.valueOf(currentPos);
int newPos = oldPos-1;
//Swap position # move up list
collections.swap(newList, oldPos, newPos);
//store ArrayList data into arrays
myDataFiles = newList.toArray(myDataFiles);
intArrayList.clear();
adapter.notifyDataSetChanged();
}
This will make our selected item move up, but it won't save the state. Meaning the item's position displayed on ListView will go back to the way it was upon closing the app

How to make a Random Layout when button clicked

Actually i want to make it Random class but then i think to much activity can make the app slow so i just want to make Relative layout Random
so i have 5 layout in one activity class
layout1 = (RelativeLayout)findViewById(R.id.layout1);
layout2 = (RelativeLayout)findViewById(R.id.layout2);
layout3 = (RelativeLayout)findViewById(R.id.layout3);
layout4 = (RelativeLayout)findViewById(R.id.layout4);
layout5 = (RelativeLayout)findViewById(R.id.layout5);
and in each layout there is the button in there to make layout random again
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){
//The code to how make layout random
}
});
}
and then how to make layout that already opened not open again if the button random was pressed? then if all layout was already opened it will open new activity class
can anyone help me explain with give some example code of that?
Initially set visibility gone to all relative layouts and put all of them into View's ArrayList.
Get random number from 0 to List size.
Get View at random position and set its visibility to Visible and remove from ArrayList.
Do same thing until ArrayList is empty.
Create new activity when ArrayList is empty.
Code:
ArrayList<View> viewList=new ArrayList<>();
initLayouts(){
layout1 = (RelativeLayout)findViewById(R.id.layout1);
layout2 = (RelativeLayout)findViewById(R.id.layout2);
layout3 = (RelativeLayout)findViewById(R.id.layout3);
layout4 = (RelativeLayout)findViewById(R.id.layout4);
layout5 = (RelativeLayout)findViewById(R.id.layout5);
viewList.add(layout1);
viewList.add(layout2);
viewList.add(layout3);
viewList.add(layout4);
viewList.add(layout5);
for(int i=0;i<viewList.size();i++){
viewList.get(i).setVisibility(View.GONE);
}
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v){
loadRandomLayout();
}
});
}
public loadRandomLayout(){
if(viewList.size()>0) {
Random r = new Random();
int number = r.nextInt(viewList.size());
viewList.get(number).setVisibility(View.VISIBLE);
viewList.remove(number);
}else{
startActivity(new Intent(this,NewActivity.class));
}
}
You could create random int as follows:
//To get a Random number 1-5 (I saw your RelativeLayouts and you've 5
Random rand = new Random();
int randomNum = rand.nextInt((5 - 1) + 1) + 1;
And then you could create a method to choose what to show :
public void ShowRelativeLayout(int rand){
switch(rand){
case 1:
if (layout1.getVisibility() == View.VISIBLE) {
//Do nothing cause it's visible
break;
} else {
layout1.setVisibility(View.VISIBLE);
break;
}
case 2:
..........
}
Make an array to store the layout indexes.
RelativeLayout[] layout = new RelativeLayout[5];
layout[0] = (RelativeLayout)findViewById(R.id.layout[0]); // 0
layout[1] = (RelativeLayout)findViewById(R.id.layout[1]); // 1
layout[2] = (RelativeLayout)findViewById(R.id.layout[2]); // 2
layout[3] = (RelativeLayout)findViewById(R.id.layout[3]); // 3
layout[4] = (RelativeLayout)findViewById(R.id.layout[4]); // 4
Make a simple random number generator.
public void FindNewLayout ()
{
Random r_generator = new Random();
int randomNum;
//now the only way to know which layouts have been shown before, you
//need to store the indexes that have been used before, somewhere.
//I recommend using an array.
// count, and the array below should be initialized somewhere else
//rather than inside the method so that only one instance of each is
//created, but for simplicity I'll just put their initialization here
int static count = 0;
//I'll explain below what count does.
// the log array that remembers each layout change
boolean[] log = new boolean[5];
do
{
//select new random number
randomNum = r_generator.nextInt((max - min) + 1) + min;
//in this case max = 4, min = 0, so replace these values in the
//equation above
// check the log to see if the number has appeared again
if ( log[randomNum] == false )
{
//Great! it hasn't appeared before, so change layout
log[randomNum] = true;
layout[randomNum].setVisibility = true;
count++; // increases step
break; //stops while because an unused layout has been found
}
}while (count<5)
//if the value of count is equal to 5 then every layout has been used
//before so the do-while code should not be run again
}// end method
And the above method should be called whenever you want to try to change layout.
Finally, you can use something like the Debugger.log("message"); statement
to be printed on the console for debugging purposes if you want, in order to find out when the layout has changed.

Please help me to random it without repeat element.

This below code it was run by repeat the same elements,
what i want is to random it without repeat.
public class khmerAlphabetExercise extends Activity {
AlphabetData data;
MediaPlayer mp;
int dataType;
int dataKey;
Random random;
private ImageView iv1, iv2, iv3,iv4;
private ImageView[] imgs = { iv1, iv3, iv3,iv4 };
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_khmer_exercise);
int[] imageViews={R.id.ex_con1,R.id.ex_con2,R.id.ex_con3,R.id.ex_con4};
//int images[]={R.drawable.con_ex_01,R.drawable.con_ex_02,R.drawable.con_ex_03,R.drawable.con_ex_04,R.drawable.con_ex_05,R.drawable.con_ex_06,R.drawable.con_ex_07,R.drawable.con_ex_08,R.drawable.con_ex_09,R.drawable.con_ex_10};
int[] images={data.getImageId()};
random = new Random(System.currentTimeMillis());
for(int v : imageViews)
{
ImageView iv = (ImageView)findViewById(v);
iv.setImageResource(images[random.nextInt(images.length)]);
}
}
}
You could keep a counter of the images left to select. And everytime you choose one you swap it in the original array with the last unselected.
So, for example, you have an array {0,1,2,3,4}. The Length of unselected will be 5, lets call it l
Choose a random number n between 0 an l-1
Your new element is the element at n.
Swap the element at n with the element at l-1, substract one to l and go back to point 1 if l bigger than 0. Go to point 4 if l == 0.
You finish
You can use Collections.shuffle
Collections.shuffle(Arrays.asList(images));
then you can just add this images one by one using a simple for loop without randomizing positions. BTW in your example images contains only one element..

Categories

Resources