When last string removed it causes app to crash - java

Ok.. Here is my problem.
I have an arraylist of stings with 10 items in it.
Then I randomize the list and display a random string in a textview.
With the last string removed the app crashes. Any tip to fix that?
Here is the code:
Collections.shuffle(learnlist);
showlearntv.setText(learnlist.get(0));
nextlearn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showlearntv.setText(learnlist.get(1));
learnlist.remove(0);

You are attempting to call get(1) on a list that may contain less than two elements.
You should add some safety checks. E.g.:
nextlearn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!learnlist.isEmpty()) {
learnlist.remove(0);
}
if (!learnlist.isEmpty()) {
showlearntv.setText(learnlist.get(0));
}
}

On the click handler, remove the item first,
learnlist.remove(0)
Then if the list has any items,
showlearntv.setText(learnlist.get(0));
Else do something else.

Related

Is there any possible way to retrieve an ArrayList value from an OnCllickListener method and save it in it's parent method?

saveBtnYes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
saveBtnYesFunc(currentYesBtnId);
tempActivityList =activityNames;
return activityNames;
}
});
When I call the saveBtnYesFunc function, it returns an ArrayList value called activityNames to the onClick thread. I want to pass that value from inside of the onClickListener method to its parent method (this code is contained within another method). The last line of code return activityNames won't work.
Is there any other way to do it?
You need to determine who is actually interested in seeing this new list. Assuming that the interested part is an instance of some class ListUsingClass, this should work.
final ListUsingClass listUser = new ListUsingClass(); // or assign to existing reference
saveBtnYes.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listUser.setActivityNames(saveBtnYesFunc(currentYesBtnId));
}
});
Your question isn't really clear, I think you want that when a Button is clicked, an Array (activityNames) is saved somewhere.
You can do this in this way, if I understood well:
class YourClass { //almost surely it extends Activity (or AppCompatActivity)
private List<String> thePlaceWhereTheArrayWillBeLocated = new ArrayList<String>(); //You should define a class varibale where the result of saveBtnYesFunc will ends up (I think that the content is of String type)
... onCreate(...) {
super.onCreate(savedInstanceState);
...
...
saveBtnYes.setOnClickListener(new View.OnClickListener() { //I don't know if it's inside the onCreate, but it could be here
#Override
public void onClick(View v) {
thePlaceWhereTheArrayWillBeLocated = saveBtnYesFunc(currentYesBtnId); //Maybe some type casts are needed
//tempActivityList =activityNames;
//return activityNames; //This line is totally incorrect
}
});
}
void wheneverFunctionYouWant() {
//do whatever you want with thePlaceWhereTheArrayWillBeLocated
}
}

onBindViewHolder increase position onClickListener

I have an activity with two buttons Next and Previous and a textview, I would like to update the textview content each time I click Next or Back
For example, If I click Next the textview should show me content from the next position or vice versa.
I think that I should be using a loop but it gives me an error when I try to do that and when I add 1 to the position (i+1) it works but it only gives me the second position, I want to get all the positions not only the second one. I don't really know if my question is clear, Hope it is :)
onBindViewHolder
#Override
public void onBindViewHolder(#NonNull final MyViewHolder myViewHolder, #SuppressLint("RecyclerView") final int i) {
myViewHolder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String nextContent = listItems.get(i).getContent();
String previousContent = listItems.get(i).getContent();
Intent intent = new Intent(v.getContext(), Main2Activity.class);
intent.putExtra("next", nextContent);
intent.putExtra("prev", previousContent);
v.getContext().startActivity(intent);
}
});
}
Main2Activity
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
itemTextView.setText(nextContent);
}
});
btnPrev.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
itemTextView.setText(prevContent);
}
});
It's bad practice to set click listeners in the onBindViewHolder method.
Why? Because onBindViewHolder is called each time the views are recycled for the new content to be displayed on the screen. Say you have a list of 1000 elements with 10 of them visible on the screen.
You scroll it to the end => Then onBindViewHolder would be called 990 times => 990 click listeners set.
You also want to dodge costly operations in onBindViewHolder() because your scrolling would be potentially slowed down.
More tips here:
Recyclerview(Getting item on Recyclerview)
A loop isn't the answer here, a loop is for automating something. This is an event (the user interacted) so it's not suitable.
The algorithm you probably want is basically the following:
User clicked an item
Find out the item index
Increment the index
Find the item with that index (by asking the list)
If it exists, do something with it
However, the issue in the code you posted is that your 'nextContent' is always the current item. So you need the following change (but be careful about bounds):
String nextContent = listItems.get(i+1).getContent();
String previousContent = listItems.get(i-1).getContent();
You current code isn't using a loop, so the onBind method should be called once for each value of i so it should not always be the second item
After your comments it appears you have buttons unrelated to the list, so now what you need to do is make it so every time you click an item in the RV or a Next/Prev, you store the correct index (as you have no access to i)
In the activity:
private int currentTextItem = 0;
public void setCurrentTextItem(int i) {
currentTextItem = i;
//the dots here will be how you get the text from the item
// probably recyclerView.findViewHolderForAdapterPosition(pos)
myTextView.setText( ... );
}
In your view holder code:
myViewHolder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//(You should have some kind of call back from viewholder to activity)
activity.setCurrentTextItem(i);
}
});
Then your next/prev:
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setCurrentTextItem(currentTextItem + 1);
}
});
btnPrev.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setCurrentTextItem(currentTextItem - 1);
}
});

Parse Save - Android: save multiple rows

I am stuck with Parse and an OnClick button. The first click works just fine and onclick, the value is added to the database, but it seems like multiple clicks don't work and won't result in the function addPoints() below being properly ran. In fact, the Toast is printed at every click but the database is modified only once and only one row is added (instead of as many rows as many clicks)
clicker.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
addPoints(user);
}
});
}
private void addPoints(String user) {
points.put("points", 10);
points.put("business", x);
points.put("user", );;
points.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
Toast.makeText(getApplicationContext(), "10 Points added", Toast.LENGTH_SHORT).show();
}
});
Any idea how to solve this?
Thank you guys
In Parse put will update the value in the data base , it won't add the value to the existing one.
you need to get the value first from the database and then add to it 10 .

Get text of dynamic generated TextView when clicking on it

I'm running through a for-loop and am generating TextViews that should be clickable because I want to start then an intent and pass the url as parameter as well as the source.
So, I've tried this
articleURL[i].setPaintFlags(articleURL[i].getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
articleURL[i].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//System.out.println(articleURL[v.getId()].getText().toString());
System.out.println(v.getId());
}
});
The problem i encounter is that the v.getId() is always 0. And when i use the commented code
System.out.println(articleURL[v.getId()].getText().toString());
I get an exception that says
java.lang.ArrayIndexOutOfBoundsException: length=10; index=-1
I just need the content of the TextView i clicked on. How exactly do i get it? articleURL[i] doesn't work because he doesn't know i then. How can v.getId() always be -1? No matter which one I click?
This here is the complete for-loop
TextView articleURL = new TextView[hashMapSize];
for (int i = 0; i < hashMapSize; i++) {
articleURL[i] = new TextView(getActivity());
articleURL[i].setPaintFlags(articleURL[i].getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
articleURL[i].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println(articleURL[v.getId()].getText().toString());
//System.out.println(v.getId());
}
});
}
You actually get the View in the parameter. Just cast it to TextView and call getText()
public void onClick(View v) {
Log.d("text",((TextView) v).getText().toString());
}
Also don't use System.out.println. This is Android, not desktop Java, and coding android is a huge difference to normal Java. You should get a book on Android and read it, otherwise your apps will start crashing pretty soon and you won't have any chance to fix them.
You may try the following:
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println(((TextView)v).getText());
}
};
// ... some loop
articleURL[i].setOnClickListener(listener);
If you also want to get index of item, try this:
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println(v.getTag());
}
};
// ... some loop
articleURL[i].setTag(i);
articleURL[i].setOnClickListener(listener);
Try this..
use this as globel
TextView articleURL[];
and then initial the articleURL like below
articleURL = new TextView[hashMapSize];
and then if your extends fragement means use below
articleURL[i] = new TextView(getActivity());
extends activity means
articleURL[i] = new TextView(this);
and
System.out.println(((TextView)v).getText().toString());

Android Notification Area Customization

I don't know whether this question get minus points, but I searched every where and my last resort is stackoverflow.
I need to add five buttons to notification area in horizontally. And each button I need to add even listener. I know it is possible to do with RemoteViews. But I never seen anyone adding event listener to each element.
These are the references if anyone need to refer.
Notifications Documentation
How to create a custom notification on android
SlidingDrawer API
You can add 5 anonymous listeners, or a single named listener.
Anonymous:
Button b1 = new Button(...);
b1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// first listener's code goes here
}
});
Button b2 = new Button(...);
b2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// second listener's code goes here
}
});
...
named is much the same, but contains a switch statement to differentiate what happens:
View.OnClickListener myListener = new View.OnClickListener() {
public void onClick(View v) {
String buttonTitle = ((Button)v).getText();
if ("title1".equals(buttonTitle)) {
// do things for the first button's click
} else if ("title2".equals(buttonTitle)) {
// do things for the second button's click
}
...
}
});
...

Categories

Resources