java.lang.IndexOutOfBoundsException... But why? - android

After 3 hours of try i decided to ask here and see if someone can provide me a solution for this error: java.lang.IndexOutOfBoundsException: Invalid index 4, size is 4
Here is my code.
private ProgressBar progressBar;
private int progressStatus = 0;
private Handler handler = new Handler();
--------------------
status.setText(getString(R.string.init));
progressBar.setVisibility(View.VISIBLE);
final Map<String,?> keys = prefs.getAll(); //4 prefs atm inside.
final ArrayList<String> props = new ArrayList<String>();
final ArrayList<String> values = new ArrayList<String>();
if (keys != null) {
for(final Map.Entry<String,?> entry : keys.entrySet()) {
props.add(entry.getKey());
values.add(entry.getValue().toString());
}
final int total = props.size();
progressBar.setMax(total);
new Thread(new Runnable() {
public void run() {
while (progressStatus < total) {
progressStatus += 1;
handler.post(new Runnable() {
public void run() {
progressBar.setProgress(progressStatus);
if (props.get(progressStatus) != null) {
writeProps(props.get(progressStatus), values.get(progressStatus));
status.setText(getString(R.string.writing) + ": " + props.get(progressStatus));
}
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (progressStatus == total) {
handler.post(new Runnable() {
public void run() {
progressBar.setVisibility(View.GONE);
progressStatus = total + 1;
myVoidOnFinish();
}
});
}
}
}).start();
}
I get the stuck here:
writeProps(props.get(progressStatus), values.get(progressStatus));
status.setText(getString(R.string.writing) + ": " + props.get(progressStatus));

The main problem is here
while (progressStatus < total) {
progressStatus += 1;
}
check value of your progress status it should be not greater than 3 while in you code it is 4 in last while index is only from 0 to 3. please set value of your progress status accordingly.
try this
while (progressStatus < total-1) {
progressStatus += 1;
}

The problem is you are setting the progressstatus value like following
final int total = props.size();
progressBar.setMax(total);
and you in the following line you are trying to get values of props ase
writeProps(props.get(progressStatus), values.get(progressStatus));
see that for the total size of 4 your progressStatus will be 4. But the maximum index of props and values will be 3. So here is the problem
you can set the value to 1 less than the size like
final int total = props.size() - 1;

You are using one extra index as you can use maximum up to 3. So please start it form zero and use less then check instead of less then equal to.

Related

Load More RecyclerView Error Cannot Call this method

I need help for this load more RecycleView, I create 'Recyclerview', first, limit 5 data and showing, but when I scroll until the end no 'ProgressBar' showing and the next data now showing, I check the 'logcat' no error only warning
this my load more function
private void loadMore() {
arraylist.add(null);
mListadapter.notifyItemInserted(arraylist.size() - 1);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
arraylist.remove(arraylist.size() - 1);
int scrollPosition = arraylist.size();
mListadapter.notifyItemRemoved(scrollPosition);
int currentSize = scrollPosition;
int nextLimit = currentSize + 5;
Log.e("currentSize",""+currentSize);
Log.e("nextLimit",""+nextLimit);
if(nextLimit <= DataNoteImformation.id.length) {
while (currentSize + 1 <= nextLimit) {
DataNote wp2 = new DataNote(
DataNoteImformation.id[currentSize],
DataNoteImformation.branchArray[currentSize],
DataNoteImformation.assetcodeArray[currentSize],
DataNoteImformation.customerArray[currentSize],
DataNoteImformation.licenseplateArray[currentSize]
);
arraylist.add(wp2);
currentSize++;
}
}else {
while (currentSize + 1 <= DataNoteImformation.id.length) {
DataNote wp2 = new DataNote(
DataNoteImformation.id[currentSize],
DataNoteImformation.branchArray[currentSize],
DataNoteImformation.assetcodeArray[currentSize],
DataNoteImformation.customerArray[currentSize],
DataNoteImformation.licenseplateArray[currentSize]
);
arraylist.add(wp2);
currentSize++;
}
}
mListadapter.notifyDataSetChanged();
isLoading = false;
}
}, 2000);
}
and the warning in logcat
W/RecyclerView: Cannot call this method in a scroll callback. Scroll callbacks might be run during a measure & layout pass where you cannot change theRecyclerView data. Any method call that might change the structure of the RecyclerView or the adapter contents should be postponed to the next frame.
and this example data
public class DataNoteImformation {
public static String[] branchArray = {"Depok","Jakarta","Bekasi","Jakarta","Jakarta","Bekasi","Bogor","Jakarta","Bekasi","Jakarta"};
public static String[] assetcodeArray = {"0092","0084","0091","0084","0084","0078","0089","0073","0027","0021"};
public static String[] customerArray = {"Kevin Sanjaya","Indah Permata","Riyan","Puri Setiawan","Herman","Iwan","Ratna","Agus","Danang","Ujang"};
public static String[] licenseplateArray = {"B 9829 SK","B 8294 LK","B 9090 NBA","B 7627 SKA","B 7637 SAK","B 6763 KIK","F 7287 NB","F8792KI","B8273KD","B7728KSI"};
public static String[] id = {"1","2","3","4","5","6","7","8","9","10"};
}
how to fix this.

Animating the Loading... textview continually

Im trying to animate the three dots of "Loading..." textview as follows,
Handler handler = new Handler();
for (int i = 100; i <= 3500; i =i+100) {
final int finalI = i;
handler.postDelayed(new Runnable() {
#Override
public void run() {
if(finalI %300 == 0){
loadigText.setText("Loading.");
}else if(finalI %200 == 0){
loadigText.setText("Loading..");
}else if(finalI %100 == 0){
loadigText.setText("Loading...");
}
}
}, i);
The problem is that ,
1. Im unable to animate it infinitely till the dialog is visible.
2. Im unable to reduce the speed of Three dots animation,
How can I be able to sort this out
Example:
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
int count = 0;
#Override
public void run() {
count++;
if (count == 1)
{
textView.setText("Loading.");
}
else if (count == 2)
{
textView.setText("Loading..");
}
else if (count == 3)
{
textView.setText("Loading...");
}
if (count == 3)
count = 0;
handler.postDelayed(this, 2 * 1000);
}
};
handler.postDelayed(runnable, 1 * 1000);

Background Colour Change by Timer

public void run() {
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText("timer=" + String.valueOf(TimeCounter));
TimeCounter++;
A.setBackgroundColor(123455+TimeCounter*100000);
}
});
}
}, 0, 1000);
I have created a timer that his role to count the running time of the application, and i want to change the background color as long as the timer goes up. what is wrong with my script?
I think the problem comes from the value that you are passing to the setBackgroundColor method.
From the doc of the class Color we can see that:
The components are stored as follows (alpha << 24) | (red << 16) |
(green << 8) | blue.
In your code, the first value that you are passing (supposing the TimeCounter starts from 0) is 123455 which corresponds to 0x0001E23F in hexadecimal.
By decomposing it, we have:
alpha=0x00
red=0x01
green=0xE2
blue=0x3F
It gives you 0% for the alpha value which means that the color is transparent.
You are adding 100000 to this value every second. So it will take you about 166 seconds (almost 3 minutes) to have a color with an alpha value greater than 0 (but it will still be invisble as the percentage of alpha will be lower than 1%).
To fix it, you can use an offset to each color to set the alpha value to 100%. For that you just have to add 0xff000000 (4 278 190 080) to the color value.
Finally, just be sure that the color value is always lower than the maximum value 0xffffffff (4 294 967 295) and it should work.
Here is a sample code:
private int offsetColor = 0xFF000000; //offset to have 100% in alpha value
public void run() {
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText("timer=" + String.valueOf(TimeCounter));
TimeCounter++;
if (TimeCounter < 167) {
A.setBackgroundColor(offsetColor+TimeCounter*100000);
} else {
/* You just reach the limit: 0xFFFFFFFF which is White */
}
}
});
}
}, 0, 1000);
With this example you can do 166 iterations (166 seconds). You can change the value that you are adding each second to adjust the duration of your animation.
Problem is the color code set in the A.setBackgroundColor();
I have simple and logical solution of this:
1.make color array like this
int[] colors=new int[]{Color.BLACK,Color.BLUE,Color.GREEN,Color.RED,Color.YELLOW};
int i=0;
set color of array by its index as i increments in Runnable:
public void run() {
runOnUiThread(new Runnable() {
public void run() {
tvTimer.setText("timer=" + String.valueOf(TimeCounter));
TimeCounter++;
A.setBackgroundColor(colors[i]);
i++;
if(i==5){
i=0;
}
}
});
}
}, 0, 1000);
See I have create new application for your color change as you required.:
public class MainActivity extends Activity {
ImageView iv;
int red = 255, green = 0, blue = 0;
int i = 0;
int a = 30;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.imageView1);
// m.postScale(2f, 2f);
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
iv.setBackgroundColor(Color.argb(a, red, green, blue));
Log.d("main", "i: " + i + " a:+ " + a + " red: " + red
+ " green: " + green + " Blue: " + blue);
a = a + 30;
// set 30 to 60 for more difference
if (a > 250) {
a = 30;
i++;
if (i == 1) {
red = 0;
green = 255;
blue = 0;
} else if (i == 2) {
red = 0;
green = 0;
blue = 255;
} else if (i == 3) {
red = 255;
green = 0;
blue = 0;
}
if (i == 3) {
i = 1;
}
}
}
});
}
}, 0, 1000);
}
}
Now Enjoy Good Luck ..

How to stop Executors.newSingleThreadScheduledExecutor(); in between the thread execution?

Below I am posting my code for the thread I am running to animate text in a RelativeLayout on top of the Page Curl activity by harism.
public void startProgress(final int index)
{
runnable = new Runnable()
{
#Override
public void run()
{
mArrWords.removeAll(mArrWords);
mStart.removeAll(mStart);
mEnd.removeAll(mEnd);
words = sentence.split(" ");
for(int i = 0; i < words.length; i++)
{
mArrWords.add(words[i]);
if(i == 0)
{
mStart.add(0);
mEnd.add(words[0].length());
}
else
{
mStart.add(mEnd.get(i-1)+1);
mEnd.add(mStart.get(i)+words[i].length());
}
/*Log.e("words", "" + "" + words[i]);
Log.e("mArrWords", "" + mArrWords);
Log.e("mStart", "" + mStart);
Log.e("mEnd", "" + mEnd);*/
}
for (int i = 0; i < mArrWords.size(); i++)
{
final int value = i;
try
{
Thread.sleep(500);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
mHandler.post(new Runnable()
{
#Override
public void run()
{
currIndex = index;
try
{
if(CurlView.ANIMATE)
tv1.setVisibility(View.VISIBLE);
else
tv1.setVisibility(View.GONE);
final Pattern p = Pattern.compile(mArrWords.get(value));
final Matcher matcher = p.matcher(sentence);
SpannableString spannableTxt = new SpannableString(sentence);
ForegroundColorSpan span = new ForegroundColorSpan(Color.RED);
while(matcher.find())
spannableTxt.setSpan(span, mStart.get(value), mEnd.get(value), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv1.setText(spannableTxt);
mHandler.sendEmptyMessage(0);
}
catch (Exception e)
{
e.printStackTrace();
mHandler.sendEmptyMessage(0);
}
}
});
}
}
};
final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
worker.schedule(runnable, CurlView.ANIMTIME+50, TimeUnit.MILLISECONDS);
}
Here, I am animating the text over images. I need to change the text for each page I am changing. I am able to change the text, however, when I turn the page, the index values I store in ArrayLists are not getting cleared. I am storing a sentence in an ArrayList named mArrWords and the indexes to refer to each word of sentence are stored in mStart and mEnd.
The problem I am facing is when the text changes, the animation starts with the previous indexes stored in mStart and mEnd ArrayLists I use to store index of a particular word. What I need to know is how do I stop my thread when the page is turned or the index of the page changes. I am calling this function inside the updatePage(final CurlPage page, final int width, final int height, final int index) method of Curl activity. I hope I was able to explain my problem. Thanks!
EDIT: I would like to specify my question more clearly. How do I check if the thread is already running before starting another thread and stop the execution of the previous thread?
removeCallbacks(..) only stops pending messages (Runnables).If runnable is started then u can not stop it in this way. See the following :
removecallbacks-not-stopping-runnable

Working Example to find the LCM of more than 2 Numbers

Android 2.3.3
I have written a program for calculating the LCM for more than 2 numbers, and it worked for me. I thought of sharing it, so that it might come in handy for those who are looking for it. This may not be the best solution, but, i did it according to my requirement. You can modify it to your need.
I have hard coded the input, and also my program uses ArrayLists to do the operations. You might want to change these.
Pre-Requisites ::: 1. Calculation of PrimeNumbers for the range of inputs.
public class PlusMinusActivity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
EditText edtxtExpression;
Button btnLCM, btnGCD;
ArrayList<String> alPrimes = new ArrayList<String>(); // Contains List of Prime Numbers
ArrayList<String> alNumbers = new ArrayList<String>(); // Contains the input => Numbers for which LCM is to be determined
ArrayList<String> alResult = new ArrayList<String>(); // Contains the numbers that make up the LCM
String strExp = ""; // Temporary String to display the result
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
edtxtExpression = (EditText)findViewById(R.id.edtxtExpression);
btnLCM = (Button)findViewById(R.id.btnLCM);
btnGCD = (Button) findViewById(R.id.btnGCD);
btnLCM.setOnClickListener(this);
btnGCD.setOnClickListener(this);
addData();
strExp = alNumbers.toString();
System.out.println("strExp Value is ::: "+strExp);
}
private void addData() {
// TODO Auto-generated method stub
//alPrimes.add(String.valueOf(1));
alPrimes.add(String.valueOf(2));
alPrimes.add(String.valueOf(3));
alPrimes.add(String.valueOf(5));
alPrimes.add(String.valueOf(7));
alPrimes.add(String.valueOf(9));
alPrimes.add(String.valueOf(11));
alPrimes.add(String.valueOf(13));
alPrimes.add(String.valueOf(17));
alPrimes.add(String.valueOf(19));
alPrimes.add(String.valueOf(23));
alPrimes.add(String.valueOf(29));
alNumbers.add(String.valueOf(1));
alNumbers.add(String.valueOf(5));
alNumbers.add(String.valueOf(7));
alNumbers.add(String.valueOf(9));
System.out.println("alPrimes ::: "+alPrimes.toString());
System.out.println("alNumbers ::: "+alNumbers.toString());
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btnLCM:
calculateLCM();
break;
case R.id.btnGCD:
calculateGCD();
break;
default:
break;
}
}
// Calculates LCM
private void calculateLCM() {
// TODO Auto-generated method stub
int i=0, count=0;
while(i < alPrimes.size())
{
count = 0;
int p = Integer.parseInt(alPrimes.get(i)); // Getting the element from PrimeNumbers List
System.out.println("Prime Number ::: "+p);
int j=0;
while(j < alNumbers.size())
{
int n = Integer.parseInt(alNumbers.get(j)); // Getting the number from Input List
System.out.println("Number ::: "+n);
if(n % p == 0 && n != 1)
{
count++; // Counts the number of integers that gets divided (% = 0) by that particular prime number
System.out.println("Count :::"+count);
}
j++;
}
if(count >= 2) // If two or more numbers, gets divided, then we do the division
{
alResult.add(String.valueOf(p)); // adding the prime number to Result list
System.out.println("Result ::: "+alResult.toString());
j=0;
while(j < alNumbers.size())
{
int n = Integer.parseInt(alNumbers.get(j));
System.out.println("Number ::: "+n);
if(n % p == 0)
{
int result = n/p;
System.out.println("Temp Result ::: "+result);
alNumbers.remove(j); // Replace the element by the result
System.out.println("After Removing ::: "+alNumbers.toString());
alNumbers.add(j, String.valueOf(result));
System.out.println("After Adding ::: "+alNumbers.toString());
}
j++;
}
i = -1; // iterate the Input list from the start
}
else if(count == 0 || count == 1)
{
boolean allPrimes = checkAllPrimes();
if(allPrimes)
{
break;
}
}
i++;
}
calculateResult();
}
// Calculates the result
private void calculateResult() {
// TODO Auto-generated method stub
int i=0;
while(i < alNumbers.size())
{
alResult.add(alNumbers.get(i));
i++;
}
int result = 1;
i=0;
while(i < alResult.size())
{
result *= Integer.parseInt(alResult.get(i));
i++;
}
edtxtExpression.setText("LCM of "+strExp+" is ::: "+result);
}
// Checks whether the elements in the ArrayList are all prime numbers
// returns true if all are prime
//
private boolean checkAllPrimes() {
// TODO Auto-generated method stub
int i=0;
boolean areAllPrimes = true;
while(i < alNumbers.size())
{
int n = Integer.parseInt(alNumbers.get(i));
if(! (alPrimes.contains(n) || n == 1))
{
areAllPrimes = false;
break;
}
i++;
}
return areAllPrimes;
}
private void calculateGCD() {
// TODO Auto-generated method stub
}
}
For the following input :::
alNumbers.add(String.valueOf(10));
alNumbers.add(String.valueOf(15));
alNumbers.add(String.valueOf(20));
alNumbers.add(String.valueOf(25));
For the following input :::
alNumbers.add(String.valueOf(10));
alNumbers.add(String.valueOf(15));
alNumbers.add(String.valueOf(20));
alNumbers.add(String.valueOf(25));
alNumbers.add(String.valueOf(110));
alNumbers.add(String.valueOf(130));
I am very new to Android and Java as well. So, if this is not a good solution, please don't mind.
Hope it helps...
You could probaly simplify your code using this idea:
static int ggt(int a, int b)
{
if (b == 0)
return a;
return ggt(b, a % b);
}
static void Main(string[] args)
{
int lcm = 1;
foreach(int x in new int[] { 1,5,7,9 })
lcm = x * lcm / ggt(x, lcm);
Console.WriteLine("{0}", lcm);
}
Syntax is c#, but hopefully readable enough. 'ggt' ist the german abbrevation for 'gcd' (greatest common divisor)
//LCM of range of numbers using JAVA
n=s.nextInt();//Reading range value
for(i=0;i<n;i++)
{
a[i]=s.nextInt(); //reading list of numbers
}
Arrays.sort(a,0,n); //Sorting the numbers
k=a[n-1]; //Assigning biggest value in the sorted array to k
j=1;
l=k;
for(i=0;i<n;i++)
{
if(k%a[i]==0)
{
continue; //checking whether all the elements are divisible by k
}
else
{
j=j+1;
k=l*j;//multiples of highest element i.e k in the sorted array
i=-1;//Assigning -1 to i, so as to check whether all the elements
//in the array are divisible by k or not from the beginning
}
}
System.out.println("LCM of range of numbers:"+k);
Input:
6
2 4 6 8 9 3
Output:
LCM of range of numbers:72

Categories

Resources