Syncing the data in arrays between activities [duplicate] - java

This question already has answers here:
What's the best way to share data between activities?
(14 answers)
Closed 5 years ago.
I am making a food order app. There is a full page ListView on my main page called MenuActivity and there is a Button when I press it, it will intent to the CartActivity page.
I have arrays food for food name, imgID for food images, butPlus butMinus to adjust the amount of food and amount to keep the amount of each food with an initial value of 0.
I have a method called addAmount , minusAmount in MenuAcitivity that will increase, decrease the amount. It is called by an Adapter of this class.
public static void addAmount(int position) {
amount[position] += 1;
}
Going to CartActivity, I used this to pass all my values.
public void goToCart(MenuItem menuItem) {
Intent in = new Intent(MenuActivity.this, CartActivity.class);
in.putExtra("list", amount);
in.putExtra("imgID", imgID);
in.putExtra("nameList", food);
startActivity(in);
}
to receive the values I created new ArrayList in CartActivity to get the data of the food that the amount in not zero.
// add components to array lists
// addList, removeList are methods to add,remove in my new ArrayList created in this class
for (int i = 0; i < amountList.length; i++) {
if (amountList[i] != 0) {
if (!foodListFinal.contains(foodList[i]))
addList(amountList[i], foodList[i], imgID[i]);
} else if (amountList[i] == 0 && !foodListFinal.isEmpty()) {
if (foodListFinal.contains(foodList[i])) {
index = foodListFinal.indexOf(foodList[i]);
removeList(amountList[index], foodList[index], imgID[index]);
}
}
}
Also, I have a method called addAmount , minusAmount in CartAcitivity that will increase, decrease the amount just like in the MenuActivity. It is called by an Adapter of this class which is not the same one with MenuActivity.
public static void addAmount(int position) {
int newAmount = (amountListFinal.get(position)) + 1;
amountListFinal.set(position, newAmount);
}
public static void minusAmount(int position) {
int newAmount = (amountListFinal.get(position)) - 1;
amountListFinal.set(position, newAmount);
}
Here is my problem..
When I decrease amount in the CartActivity to 0 and I went back to MenuActivity it correctly says 0, but if I switch to CartActivity again the app crashes with an error saying index out of bound.
Please help me with this, or is there any better way to do this please enlighten me. Thank you

for which array caused this error : " saying index out of bound." , foodList or amountList array ? It's gonna help you

I would suggest to use secondary storage to store your changes. Also passing whole array to another activity is not recommended.Use any database to insert change in it and then in cart activity retrieve all data.
This way ,you can achieve same state of amount in various objects.

Related

How can i use a variable from an Activity to another Activty?

In my MainActivity i have a score variable,
int score = 0;
however i have another activity which is the DisplayScore activity (which displays the score) txtFinalScore.setText("Score: " + score);
how can i use that same variable form my MainActivity to my DisplayScore activity so that i can display the score?
If I've understood well, here's how you should do it.
public class Main {
public static void main(String[] args) {
int score = 0; // the main activity thing
int displayScore = score; // the thing to use the same value as score
System.out.println("Score : " + displayScore); // to simulate the setText
}
}
This question explains perfectly how to use putExtra() and getExtra() methods for the Intent in Android, because I think that's what you need.
Also, if you find this difficult, you can store the score value into a sharedPreference and retrieve it from another activity. You can see the docs here.

Shopping cart can't hold currently items when I go back to the menu page and add a new items

I have created a shopping cart application, and it can add items to the cart. But the issue is it can't add another new item when I go back to the menu page.
https://i.stack.imgur.com/Nkxob.jpg
https://i.stack.imgur.com/j3Gh4.jpg
So, it worked for the first time when I added: "Ice Coffee for 3 and Red Tea for 2" to the cart.
Then when I go back to the menu page and add another new item: "Black Tea for 5, and Green for 2".Then the new items can be added to the cart. But for the "Ice Coffee and Red Tea" was changed the quantity to 1. It can't keep the last quantity. https://i.stack.imgur.com/K2fcC.jpg
How can I fix this issue so that it can hold the current items of the quantity, and add another new item when I go back to the menu page?
public class CartActivity extends AppCompatActivity {
ListView cartListView;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.cart, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.cart_delete_item:
Main.getAddedItems().clear();
Toast.makeText(this, "The cart has been cleared", Toast.LENGTH_SHORT).show();
CartAdapter cartAdapter = new CartAdapter(this, getOrganizedAddedItems());
cartListView.setAdapter(cartAdapter); //HW log---Yes or No
break;
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
break;
}
return true;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cart);
cartListView = findViewById(R.id.cart_listView);
CartAdapter cartAdapter = new CartAdapter(this, getOrganizedAddedItems());
cartListView.setAdapter(cartAdapter);
}
private List<CartItem> getOrganizedAddedItems() {
List<com.example.shoppingcar.MenuItem> addedItems = Main.getAddedItems();
List<CartItem> organizedAddedItems = new ArrayList<>();
int quantity = 1;
double totalPrice;
for (int i = 0; i < addedItems.size(); i++) {
com.example.shoppingcar.MenuItem currentMenuItem = addedItems.get(i);
for (int y = i + 1; y < addedItems.size(); y++) {
if (currentMenuItem.getName().equals(addedItems.get(y).getName())) {
quantity++;
addedItems.remove(y);
y--;
}
}
totalPrice = currentMenuItem.getPrice() * quantity;
organizedAddedItems.add(new CartItem(currentMenuItem.getName(), quantity, totalPrice));
quantity = 1;
}
return organizedAddedItems;
}
}
I think I need to create a method or something else to hold this method of private List<CartItem> getOrganizedAddedItems() But I don't know which method can work, and where I need to put the new method into the code. I mean do I put the new method inside of that private List<CartItem> getOrganizedAddedItems() or inside of protected void onCreate(Bundle savedInstanceState).
Can someone help me with this issue?
Thank you.
That private List<CartItem> getOrganizedAddedItems() and onCreate() are both methods themselves, so you wouldn't be adding a method inside them. It looks like you're making a ListView, and adding rows to that, with each row containing a CartItem object.
If that is correct, then this nested for loop
for (int y = i + 1; y < addedItems.size(); y++) {
if (currentMenuItem.getName().equals(addedItems.get(y).getName())) {
quantity++;
addedItems.remove(y);
y--;
}
}
is unnecessary and you could just use something like:
for( MenuItem currentMenuItem : addedItems ){
totalPrice = currentMenuItem.getPrice() * currentMenuItem.getQuantity();
organizedAddedItems.add(new CartItem(currentMenuItem.getName(), quantity, totalPrice));
}
This would require a small change to the Menuitem, to add a quantity parameter to it which can be initialized to 1 and changed as needed. In return this will give you easier access to setting and retrieving quantities, no new methods needed, and as a bonus eliminate the need for nested for loops which will improve your performance (granted, pretty slight in this case, but still better practice).
For the last paragraph of your question, this seems to be a separate issue but it's not quite clear what you are asking, and you will need to add more details as to how you are storing the list of CartItem as opposed to the MenuItem and what you are trying to achieve to get more help.
Additionally, you could possibly be simplifying your code further, by removing the CartItem altogether, and simply keeping a single class variable tracking the total price for all the objects instead, but again, to know for sure you would have to describe the structure of your code further.

Add and remove item of recyclerview depending on distance

I am developing an application where a list of message (MESSAGE_RECIEVED) should be visible only in a certain distance (50, 100, 200, 300 or 400 meters)
For that I have an ArrayList of messages (MESSAGE_RECIEVED), a RecyclerView with a custom adapter and a fragment containing the RecyclerView and give it my ArrayList.
The methods I have now are the following:
To remove an entry (in my adapter):
public void removeAt(int pos) {
mMessagesList.remove(pos);
notifyItemRemoved(pos);
notifyItemRangeChanged(pos, mMessagesList.size());
}
To add an entry (in my adapter):
public void addAt(int pos, Message m){
mMessagesList.add(pos, m);
notifyItemInserted(pos);
}
Finaly my code that determine if an item is too far away:
ArrayList<String[]> operation = new ArrayList<>();
for (int i = 0; i < MESSAGES_RECEIVED.size(); i++){
if(dist <= distMax){
if(!MESSAGES_RECEIVED.get(i).isDisplayed()){
operation.add(new String[]{"add", String.valueOf(i)});
MESSAGES_RECEIVED.get(i).setDisplayed(true);
}
} else {
operation.add(new String[]{"remove", String.valueOf(i)});
}
}
for (String[] values : operation){
Log.i(TAG, "recalculateDistance: " + values[0] + " " + values[1]);
if(values[0].equals("add")){
int pos = Integer.valueOf(values[1]);
mRecyclerViewAdapter.addAt(pos, MESSAGES_RECEIVED.get(pos));
} else if(values[0].equals("remove")){
int pos = Integer.valueOf(values[1]);
mRecyclerViewAdapter.removeAt(pos);
}
}
This code do not work as items are removed from my ArrayList of message. I cannot delete them as they are used elsewhere (and I have IndexOutOfBoundsException because the position is out of the scope of the ArrayList).
On top of that I cannot delete them because if they are in the defined range people will not be able to see them.
Is there a way to hide items without deleting them? I though of duplicating my list of messages, don't know if this might work.
Thanks in advance guys!
Ok, I finally found somthing to make it works. I created another ArrayList and placed it in a static class (so that I can update the display from multiple place in the app)
Here is the methos I created
public static void updateDisplayedMessages(){
MESSAGES_DISPLAYED.clear();
getDistance(MESSAGES_RECEIVED);
for(Message m : MESSAGES_RECEIVED){
float dist = m.getDistance();
int distMax = Integer.valueOf(VALUE_PREF_RADIUS_GEO_FENCING);
if(dist < distMax){
MESSAGES_DISPLAYED.add(m);
}
}
}
Once this is called I call notifyDataSetChanged from my fragment and that's it! Probably not the most efficient way of implementing it but it works

how to use method on specific object from arraylist

EDIT2: Sorry all... I believe it is due to the lack of understanding of question that cause this misconception. After reading through, I think what they want is for the return value of getWinningPoint() be the biggest number among the players and yet still <=21. so that in the game output, can loop each player to get their card point again and compare it to this winningpoint. I thank all of your input and help. Moderator or Admin can close this thread. Thanks again.
I would like to find out how to access the particular object in the arraylist so that i can cast the method on it. In a overall view, I am able to make method that apply to all items in the arraylist of players (distributeCardsToPlayer). But my 2nd method of getWinningPoints() is a int that sum up all the cards the particular player in arraylist players have. The winningPoint is a individual result which will ultimately be used in printWinners() method. I'm only familiar with accessing a obj with "Player player = players.get(0);" but in this case the "player" itself will be calling getWinningPoints() to check their own result.
P.S - I am not sure how to put it properly,and hopefully someone can point me to the right direction.
import java.util.*;
public class ModifiedBlackJack
{
protected ArrayList<Card> gameDeck;
protected ArrayList<Player> players;
public ModifiedBlackJack(ArrayList<Player> players)
{
this.players=players;
}
public void distributeCardsToPlayers()
{
Scanner console = new Scanner(System.in);
for (Player player : players)
{
player.drawACard(getACardFromDeck());
player.drawACard(getACardFromDeck());
System.out.println(player.getName()+": " + player.toString());
System.out.print("Draw another card? (y/n): ");
char input = console.nextLine().toLowerCase().charAt(0);
if(input == 'y')
{
player.drawACard(getACardFromDeck());
}
}
EDIT2: After reading through, I think what they want is for the return value of getWinningPoint() be the biggest number among the players and yet still <=21. so that in the game output, can loop each player to get their card point again and compare it to this winningpoint.
public int getWinningPoints()
{
int wp=0;;
int point=0;
for (Player player:players)
{
point = player.getCardsPoints();
if (point>=21 && point>wp)
{
wp=point;
}
}
return wp;
}
In the Player class, there is a function for summing up all the cards point
public int getCardsPoints()
{
int point=0;
for (Card c: cards)
{
point=point+c.getPoints();
}
return point;
}
I am new to java and any help or guidance is very much appreciated.
Thank You
You may be overthinking this, and the method getWinningPoints isn't entirely required.
Because you already have getCardsPoints declared in Player, and you already have an instance of Player to work with in your loop, the only thing you realistically need to do is...invoke it.
System.out.println(player.getName() + "Chips: " + player.getChips() + "[]" + player.getCardsPoints());
Whatever conditions you need to satisfy the min parameter should be done inside of this loop; that is, conditionally print the values that are larger than min.
If you want to invoke a Player class method you need to have a player object to call a method that it "owns".
Pass the player object to the method and accept the player object in getWinningPoints().
Call
getWinningPoints(player)
Declaration
public int getWinningPoints(Player localPlayer)
{
return localPlayer.getCardsPoints();
}

finding the number of a variable in Object arrays in different classes (java)

Presume we have a class Student and a class Activity.
class Student {
private Activity[] myActivites;
public Activity[] getAct() {
return this.myActivites
}
}
class Activity {
private String name;
public String getName(){
return this.name;
}
private Student[] members;
}
the members array represents all the students that go to this particular activity, while the myActivites array in Student represents all the different activites the particular student is visiting.
How would I go about writing an INT method in the activity class that returns the number of differently named activites that all of the students in this particular activity are visiting (so, two different Activity objects can have the same name!)
EDIT:
Thanks for your concerns guys. It's actually not homework, I'm preparing for a test next week.
Hope you will forgive me for not translating the code into english, as it takes quite some time.
It's a part of a larger program I have to write. So far, I've done something like this:
public int steviloRazlicnihDejavnosti() {
int najboljPriden = this.clani[0].getSteviloKrozkov();
for (int i=1; i<this.clani.length; i++) {
int trenutnaPridnost = this.clani[i].getSteviloKrozkov();
if (trenutnaPridnost > najboljPriden) {
najboljPriden = trenutnaPridnost;
}
}
String[][] krozkiClanov = new String[this.clani.length][najboljPriden];
for (int i=0; i<this.clani.length; i++) {
Ucenec trenutni = this.clani[i];
Krozek[] krozkiTrenutnega = trenutni.getKrozki();
for (int j=0; j<krozkiTrenutnega.length; j++) {
krozkiClanov[i][j] = krozkiTrenutnega[j].getDejavnost();
}
}
int stevec = 0;
return;
"Krozek" is the class Activity.
"Ucenec" is the class Student.
at first, I figure out, which student has the most activites and then set a 2d string array of this length (and the length of all students), which I fill with the names of the activites. Then, I was thinking of checking the 2D array (haven't written that up yet), but believe that this will take too much time - I basically just prolonged the same problem I was facing before.
Hope this shows that I've actually put some work into this.
I've also tried solving it with adding an extra boolean attribute "HasBeenChecked", and would not count any object that "HasBeenChecked", but figured that this did not help with recodnising the duplicates of the names.

Categories