Accessing String Array in Button Click - android

I have a string array :
private String [] arrFilePaths=new String[4];
and I have a funtion which returns strings and im adding that to array:
#Override
public void accept(List<File> files) throws Exception {
int size = files.size();
while (size-- > 0) {
arrFilePaths[size]=files.get(size).toString();
}
}
Now i have a button and I am accessing array inside of it:
#Override
public void onClick(View v) {
if(arrFilePaths[0]==null){
//some code
}else {
//some code
}
Now the problem is arrFilePaths only return strings in button click sometime. most of time its returning null.The data always getting inserted to array before button click. so i dont know whats going on.
Yes i have tested in debug mode and arrFilePathsis getting data inserted, but somehow after the button click it saying null(even though I am using same variable).
Can anyone explain about this weird output? Thanks!

As far as I can see, you will be getting null every time when your List<File> files has fewer elements than arrFilePaths array.
Imagine this is files list [L1 , L2 , L3]
And your array is [A1 , A2 , A3 , A4 , A5 , A6]
As you're writing from end, the last element from the end of files will appear at last position of arrFilePaths so on so force.
Finally, array will look like [null, null, null, L1 , L2 , L3].
Obviously, the 1st element of this array will be null.

I am not sure how you are seeing the values sometimes because to me it seems like a logical problem in below code
while (size-- > 0) {
arrFilePaths[size]=files.get(size).toString();
}
Lets assume your size is 3 so you travel here in the reverse order. So you fill the position 3 and 2 and 1 but as soon as size becomes 0, your condition fails and it never sets the value for 0th element.
then your if condition checks -
if(arrFilePaths[0]==null)
So its checking if 0th element is null which is obviously the case because your while loop didn't let it enter there. hence no data.
so if your size is more than 4 in that case your 0th element will get filled as your arrFilePaths can only take 4 elements

In my opinion you should Modify this line
while (size-- > 0)
like this
while (size-- >= 0) {

Just replace that while with a fori, I don't see any reason at all why you would want to populate that array from the end to the front.

Related

Set<String> Sort and remove specific value

i'm looking for this problem for hours.
I have autocompletetextview which is shows the all inputs in dropdownlist.
I keep values in Sharedpreference.
AutoCompleteTextView texttutar;
ArrayAdapter<String> adapter;
SharedPreferences.Editor editor;
SharedPreferences pref;
Set<String> hs;
ONCREATE ----
pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
editor = pref.edit();
hs = pref.getStringSet("set", new HashSet<String>());
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line);
texttutar.setAdapter(adapter);
if(!texttutar.getText().toString().isEmpty()){
hs.add(texttutar.getText().toString());
editor.clear();
editor.putStringSet("set",hs);
editor.commit();
}
// SortedSet<String> sortedSet = new TreeSet<String>(hs);
// Toast.makeText(getApplicationContext(), "" + sortedSet.first(), Toast.LENGTH_LONG).show();
// if(hs.size()>=5)
// hs.remove(hs.iterator().next()); Removing last value of hs
adapter.clear();
adapter.addAll(hs);
texttutar.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
adapter.getFilter().filter(null);
texttutar.setThreshold(1);
}
return false;
}
});
texttutar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
texttutar.showDropDown();
}
});
Now, this code works perfectly.
But i need two more things to do.
First problem : When i add values like
100 - 101 - 102 - 103 -104 - 105
its showing me the values like that :
102 - 100 - 105 - 103 - 101 - 104
I dont know why. It must sort by time.
Second problem : As you can see i can remove the last value but i didnt find any solution for first item.
I tried something like Treeset but its not important. Important is i should delete the value of Set (Sharedpreference).
After autotextview shows 5 value, it must delete the first item.
Like that : I'm adding this values. 110-200-300-400-690 and then 900
When i add 900 the code must remove the first value (110 ) then first value will be 200 . Its work like that.
Sets are unsorted. THe definition of a Set is that it keeps track of a group of items and that you can test quickly whether an item is in it or not (typically in O(log n) or O(1) time). There is no promise of order, and in fact a set usually uses balanced binary trees or a hash internally, purposely losing order for speed.
For what you want, a Set is not the appropriate data structure. You want a queue. A queue is an ordered group of items where you add them to one side and remove from the other. Particularly it seems like you want a fixed size queue. I suggest you use one, rather than trying to make a data structure that's inappropriate work.

Setting Text Based on values held in ArrayList

This is driving me a little mad since I know this should be very simple but I am not getting the desired affect.
I have the following arraylist
private List<String> tagStringArray = new ArrayList<>();
Then later I have a method that creates dynamic buttons, based on ID values pulled across from my Retrofit instance.
In my method, I have a count to help me set the title of the button but I also add the values of count to an ArrayList for use in another method.
I have taken a snip of relevant information from the method mentioned.
count = 1;
if (!questionNumber.equals("") && !questionNumber.equals(null)) {
for (final Object value : list) {
try {
/*Dynamically create new Button which includes the question number
*/
final AppCompatButton btn_question = new AppCompatButton(getActivity());
/*LayoutParams (int width, int height,float weight)
As LayoutParams is defaulted in px, I have called a method called dpToPX to make sure
the dynamically added EditText is the same size on all devices.
*/
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dpToPx(280), dpToPx(45), 1);
btn_question.setBackgroundColor(Color.parseColor("#3B5998"));
btn_question.setTextColor(Color.WHITE);
btn_question.setText("Question "+count);
//set the Tag based on its position in the XML
tagStringArray.add(String.valueOf((count)));
count++;
If a user clicks on say Question 1 Button, I want my fragment to say Question 1, so to try and achieve that, I have tried doing the following:
String tags = String.valueOf(tagStringArray);
tags = tags.substring(1, tags.length() -1);
String[] currentTag = tags.split(",");
if (currentTag[0].contains("1")) {
tv_setQuestions_edit.setText("Question 1");
}else if(currentTag[1].contains("2")) {
tv_setQuestions_edit.setText("Question 2");
}
But this will always set the title to Question 1 and I am not sure what is going wrong.......
If I use the following toast Toast.makeText(getActivity(), Arrays.toString(currentTag), Toast.LENGTH_LONG).show(); it shows [1,2] so I know they are being added ok.
I did look into using tags by doing:
public static int KEY_COUNT=0; public static int KEY_VALUE=1;
btn_question.setTag(KEY_VALUE,value);
btn_question.setTag(KEY_COUNT,count);
But for some reason, when I add more than one tag (as I need a minimum of 2), my dynamic button is missing from the layout. But for some reason when only 1 tag - like this btn_question.setTag(value); is used, it shows up fine (I have a feeling its some issue with my fragment). Therefore I am trying to think of a workaround in the meantime.
Any help or guidance would be really appreciated.
It's because
currentTag[0].contains("1")
is always true. The first item of currentTag always contains "1".
Instead of doing this, why don't you just do String titleForFragment = myButton.getText() in the onClick method for the button? That way, you can set the same onClickListener on all the buttons, and it will reduce the amount of code you need to write.

How to make a button give different results everytime when user tap it?

I have a button and I want it to change the text that I positioned above the button to something random everytime the user press it. How can I do it?
I want to look something like this:
"Hello"
**press**
"Why did you press?"
**press**
"Don't do that again, or..."
**press**
"You just did!"
Here is the code of the button and the text.
dontPressButton.setOnClickListener(
//Sets the button to wait for the press
new Button.OnClickListener(){
public void onClick(View V) {
//Selects the text field to be changed
TextView textChange = (TextView) findViewById(R.id.textChange);
//Changes the text
textChange.setText(string.textChange2);
}
}
);
There is no magical way to have it randomly change the text, you have to program it to do that. You are going to have to create an array of responses and then in the button's code, tell it to cycle through those responses. So for example:
private String[] responseArray = {"Hello", "Why did you press?", "Don't do that Again", "You Just did!" }
private int numTimesPressed = 0
dontPressButton.setOnClickListener(
//Sets the button to wait for the press
new Button.OnClickListener(){
public void onClick(View V) {
//Selects the text field to be changed
TextView textChange = (TextView) findViewById(R.id.textChange);
//Changes the text
//note this line will cause an error if there is not enough values in the array. You would have to write a catch for this
textChange.setText(responseArray[numTimesPressed++]);
//if you want random, you'll have to change the array index you are accessing to random value between the array's bounds
}
}
);
You'll definitely need an array of string responses. Afterwards, the first approach I would use is to use a random number generator, and then just link it back to your array. Unfortunately I'm not able to write the code, since I don't know the exact syntax, but in pseudocode:
string array[x]={"Hello","Why did you press?",...};//Number of string responses (in this case it's 4)
int random_number;
random_number=RandomNumberGenerator(1,x);//1 and x are the lower and upper bounds
switch (random_number)://If you don't know, switch is basically a simplified if-else system
case 1:print "Hello";
.........
There are many random number generators online that you can use, depending on the language. Hope this helped!
P.S: Maybe you'll want to fine-tune your responses to make them more natural. For example, you probably want to re-roll your response if you get two of the same one in a row.

Linking two NumberPicker views with onValueChanged causes unpredictable crashes

I've created a dialog containing two NumberPicker views. The first contains a list of groups, the second contains the items from the selected group:
Group Group Items
1 2: Group 2 Item 2
[2] [3: Group 2 Item 3]
3 4: Group 2 Item 4
I'm hooking in to the setOnValueChangedListener in the first NumberPicker to populate the second NumberPicker.
mNumberPickerGroup.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
#Override
public void onValueChange(NumberPicker numberPicker, int from, int to) {
int size = mData.getItemsForGroup(to).size();
String[] strings = mData.getItemTitlesForGroup(to);
mNumberPickerItems.setMinValue(1);
mNumberPickerItems.setValue(1);
mNumberPickerItems.setMaxValue(size);
mNumberPickerItems.setDisplayedValues(strings);
}
});
This basically works - until, in certain circumstances, changing the group a few times can cause a crash in the NumberPicker class, when setting the setDisplayedValues strings.
The error is an array index out of bounds exception in the numberpicker for items, a line to do with the string array I passed in. I've set a break point in the update code above, and verified that the String array is always the correct size for the number of items set between min and max value on the number picker, so this has stumped me.
java.lang.ArrayIndexOutOfBoundsException: length=22; index=22
at android.widget.NumberPicker.ensureCachedScrollSelectorValue(NumberPicker.java:1768)
at android.widget.NumberPicker.initializeSelectorWheelIndices(NumberPicker.java:1583)
at android.widget.NumberPicker.setMaxValue(NumberPicker.java:1390)
at uk.co.my.app.fragments.GroupMarkUptoDialog.updateItemPicker(MarkUptoDialog.java:99)
I'm about to start reading through what happens in the NumberPicker to figure out if I'm using it wrong, but any suggestions would be welcome. "ensureCachedScrollSelectorValue" makes me think I need to reset the numberpicker somehow before updating it with new data but I'm not sure.
Can anyone see what I'm doing wrong here?
I realise the NumberPicker is not really a String picker, so if anyone has a better suggestion for how to achieve this sort of UI I'm all ears. Otherwise, I'm heading down the route of trying to implement some kind of debouncer, to update the items picker once all activity on the group picker is complete.
It happens when you setDisplayedValue(String[]) many times.
If the string[]'s length is larger than the current getMaxValue(), Exception happens!
My solution
use
picker.setMaxValue(0);
before
picker.setDisplayedValues(stringArr);
My code
cityPicker.setMaxValue(0);
try {
cityPicker.setDisplayedValues(citySet.toArray(new String[citySet.size()]));
} catch (Exception e) {
Log.e("Ninja", "cityPicker.setDisplayedValues(citys) occurs Error. province is " + province);
}
cityPicker.setMaxValue(citySet.size() - 1);
If you use indexes started from 1 then use:
int size = mData.getItemsForGroup(to-1).size();
Use this to change second picker (if current value is above maximum it will set it to new maximum):
int i = mNumberPickerItems.getValue();
int max = strings.length;
if (i > max)
i = max;
mNumberPickerItems.setMinValue(1);
mNumberPickerItems.setMaxValue(1);
mNumberPickerItems.setDisplayedValues(strings);
mNumberPickerItems.setMaxValue(max);
mNumberPickerItems.setValue(i);
And try to use values as indexes, i.e.
minValue=0
maxValue=strings.length-1

Dynamically updating AutoCompleteTextView sometimes doesn't show suggestions

I am dynamically updating my AutoCompleteTextView on every 3rd / 4th letter.
For some reason, about 5-10% of the time when the user types the third letter, though I know for sure I am making a valid arraylist and populating the AutoCompleteTextView, it does not show for unique cases. Something I noticed that was consistent was that the list of words that did not show up were from length 5-15 (others range 50+)
Any idea what is going ? Am I missing something about AutoCompleteTextView, where it doesn't think showing 10 or so suggestions is worth it if the datalist is not as big? Should I add irrelevant filer data or would that impact performance? Thanks
Here is some relevant source code..
Textwatcher for text view checks that;
if (((start + count) == 3) || ((start + count) == 4)
|| ((start == 3) && (before >= 1))) {
if (!last.equals(s)) {
thread = new Thread(new AutoCompleteThread(s));
thread.start();
}
}
in my custom thread I group up words .. then i call this on my text view and adapter;
if(words.size() > 0)
{
last = s;
// adapter.clear();
// for(String e : words)
// adapter.add(e);
// adapter.notifyDataSetChanged();
adapter = new ArrayAdapter<String>(
getActivity(), android.R.layout.simple_list_item_1, words);
textView.setAdapter(adapter);
textView.showDropDown();
}
Turns out there is a weird glitch that happens very often if my dynamically loading list is very small and my original list (which comes from my RES folder) is substantially large (500 or so). It doesn't glitch out when the dynamically loaded list is large, perhaps it gives enough time to the AutoCompleteTextView to show suggestions while loading? Not sure about that.
Anyways, the solution was to lower my original size of the arraylist in my res folder

Categories

Resources