retrieve selected value from multiple spinners in a arraylist - android

I am developing an e-commerce android application using Firebase real-time database and i am using spinners to show my products category wise in multiple spinners. What i want is when user selects something from first spinner and press add button then that value comes in an array-list named current_products and then user selects something or not from rest of spinners and these values should keep coming to current_products(array-list). I have add button for every spinner so when user press add button for a specific spinner it should get the selected product from that spinner and add into current_products. I am trying to do the same thing the problem i am facing is when a user selects something from a spinner and presses add button the value gets added in current_products but when again user open that spinner and select a different product then this product is also added in current_products instead of removing the previous product from that spinner and adding the newly selected product.
Here is look of my database for further understanding
here is my code:
private Spinner scarfs_spinner, buttons_spinner, pins_spinner, laces_spinner;
private Button addScarfBtn, addButtonBtn, addPinsBtn, addLacesBtn;
private DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
private ArrayList<String> scarfsList = new ArrayList<>();
private ArrayList<String> buttonsList = new ArrayList<>();
private ArrayList<String> lacesList = new ArrayList<>();
private ArrayList<String> pinsList = new ArrayList<>();
private ArrayList<Products> all_products = new ArrayList<>();
private ArrayList<String> current_products = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_customization);
scarfs_spinner = (Spinner) findViewById(R.id.scarfs_spinner);
buttons_spinner = (Spinner) findViewById(R.id.buttons_spinner);
pins_spinner = (Spinner) findViewById(R.id.pins_spinner);
laces_spinner = (Spinner) findViewById(R.id.laces_spinner);
addScarfBtn = (Button) findViewById(R.id.addScarfBtn);
addButtonBtn = (Button) findViewById(R.id.addButtonsBtn);
addPinsBtn = (Button) findViewById(R.id.addPinsBtn);
addLacesBtn = (Button) findViewById(R.id.addLacesBtn);
showDataSpinner();
}
private void showDataSpinner()
{
databaseReference.child("Products").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot)
{
for(DataSnapshot item : dataSnapshot.getChildren()) {
if (item.child("category").getValue(String.class).equals("Scarfs"))
{
scarfsList.add(item.child("pname").getValue(String.class));
}
if (item.child("category").getValue(String.class).equals("Buttons"))
{
buttonsList.add(item.child("pname").getValue(String.class));
}
if (item.child("category").getValue(String.class).equals("Pins"))
{
pinsList.add(item.child("pname").getValue(String.class));
}
if (item.child("category").getValue(String.class).equals("Laces"))
{
lacesList.add(item.child("pname").getValue(String.class));
}
all_products.add(item.getValue(Products.class));
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(CustomizationActivity.this, R.layout.style_spinner, scarfsList);
ArrayAdapter<String> arrayAdapter1 = new ArrayAdapter<>(CustomizationActivity.this, R.layout.style_spinner, buttonsList);
ArrayAdapter<String> arrayAdapter2 = new ArrayAdapter<>(CustomizationActivity.this, R.layout.style_spinner, pinsList);
ArrayAdapter<String> arrayAdapter3 = new ArrayAdapter<>(CustomizationActivity.this, R.layout.style_spinner, lacesList);
scarfs_spinner.setAdapter(arrayAdapter);
buttons_spinner.setAdapter(arrayAdapter1);
pins_spinner.setAdapter(arrayAdapter2);
laces_spinner.setAdapter(arrayAdapter3);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
addScarfBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
current_products.add(scarfs_spinner.getSelectedItem().toString());
}
});
addButtonBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
current_products.add(buttons_spinner.getSelectedItem().toString());
}
});
addPinsBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
current_products.add(pins_spinner.getSelectedItem().toString());
}
});
addLacesBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
current_products.add(laces_spinner.getSelectedItem().toString());
}
});
}

Assign the item to a particular array position and before adding an item from the spinner, check if that position in the database is empty then populate it else clear the position content before adding (replacing) the new item.

Related

Drop down size of spinner

I am dynamically populating the spinner based on response from previous selected item.Though the size of list is more than 1 ,size of drop down is sometimes showing only one item(Slider is working). It is not happening everytime.Sometimes it is showing maximum size and sometimes not.
Maximum size of drop down is 400dp.
<com.jaredrummler.materialspinner.MaterialSpinner
android:id="#+id/spinnerCollege"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
app:ms_dropdown_max_height="400dp"
app:ms_background_color="#color/offWhite"/>
new CityPresenter().getCities(new OnEntitiesReceivedListener<City>(this) {
#Override
public void onReceived(final List<City> cities) {
UpdateProfileActivity.this.cities = cities;
final List<String> cityNames = new ArrayList<>();
for(City city : cities){
cityNames.add(city.getName());
}
// Collections.sort(cityNames);
Log.d(TAG,cityNames.toString());
cityNames.add(0,"Select City");
citySpinner.setItems(cityNames);
}
}
Expected to show more than one item in drop down but showing only one item.
I don't know how you have set your adapter but this is generally how I get dynamic spinners working.
Dynamic List Spinner
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get reference of spinner from XML layout
Spinner spinner = findViewById(R.id.mySpinnerId);
//Using this button to trigger spinner list change
Button myButton=findViewById(R.id.myButtonId);
final List<String> myArrayList= new ArrayList<>();
myArrayList.add("Some String");
myArrayList.add("Some Other String");
//And....so on
final ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_item,myArrayList);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
//Triggering the spinner list change using a button
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myArrayList.add("New Item");
adapter.notifyDataSetChanged();
}
}
}
Hope this helps you to identify and resolve the issue.

Get Can't pass null for argument 'pathString' in child() error

I having some trouble with how to use a Button to access another activity with data from firebase. I'm just getting an error "Can't pass null for argument 'pathString' in child()". But when I try in another activity with OnItemClick on a listview item it works. Why is that?
What I'm trying to do is: I have a activity with a listview that stores and get data from firebase. What I want is, if I click on one of the items in that listview I want a new activity with buttons, and these buttons will get me to another activity with a listview that are related to the first activity (related data). So the activity with the buttons are the same activity for every listview items i click on, like just a "dummy" activity. Is this possible?
Here is the code:
lvjobbinfo works fine, but add doesn't. I want lvjobbinfo and add to do the same.
public class MainActivity extends AppCompatActivity {
EditText etinfonavn;
ListView lvjobbinfo;
TextView tvjobbnavn;
Button add;
DatabaseReference databaseJOBBINFO;
List<Main> jobbinfo;
public static final String infonavn = "infonavn";
public static final String infoid = "infoid";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
databaseJOBBINFO = FirebaseDatabase.getInstance().getReference().child("Jobbinfo");
lvjobbinfo = (ListView)findViewById(R.id.lvjobbinfo);
lvjobbinfo.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
Main main = jobbinfo.get(i);
Intent intent = new Intent(getApplicationContext(), Notater.class);
intent.putExtra(infoid, main.getInfoId());
intent.putExtra(infonavn, main.getInfonavn());
startActivity(intent);
return true;
}
});
tvjobbnavn = (TextView)findViewById(R.id.tvjobbnavn);
etinfonavn = (EditText) findViewById(R.id.etinfonavn) ;
add = (Button)findViewById(R.id.add);
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent add = new Intent(MainActivity.this, Notater.class);
startActivity(add);
}
});
Intent intent = getIntent();
jobbinfo = new ArrayList<>();
String id = intent.getStringExtra(Jobbliste.jobbId);
String navn = intent.getStringExtra(Jobbliste.jobbnavn);
tvjobbnavn.setText(navn);
databaseJOBBINFO = FirebaseDatabase.getInstance().getReference("Jobbinfo").child(id);
}
#Override
protected void onStart() {
super.onStart();
databaseJOBBINFO.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
jobbinfo.clear();
for (DataSnapshot infosnapshot : dataSnapshot.getChildren()) {
final Main main = infosnapshot.getValue(Main.class);
jobbinfo.add(main);
final listMain infolistadapter = new listMain(MainActivity.this, jobbinfo);
lvjobbinfo.setAdapter(infolistadapter);
infolistadapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

passing data from custom adapter to another activity

I have a listview which consist of items with prices. My listview also has a Delete button. I also have a textview at the bottom part of the layout which is not part of the listview and it shows the total amount. I can successfully remove the item from my listview. What I want is that when the item is removed, the total amount will also change.
Here is a part of my adapter where i must do some actions
holder.del.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
remove(getItem(position));
}
});
and here is my Activity where my textview of amount is found.
public class Cart extends MainActivity {
TextView amount_total;
ListView cartList;
CartCustomAdapter cartCustomAdapter;
String name, price;
static ArrayList<Order> cartArray = new ArrayList<Order>();
static Double total_amount = 0.00d;
static Double temp = 0.00d;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cart);
amount_total = (TextView) findViewById(R.id.total_tv);
Bundle bundle = getIntent().getExtras();
Button checkout = (Button) findViewById(R.id.check_out);
Button add_item = (Button) findViewById(R.id.add_item);
name = bundle.getString("i_name");
price = bundle.getString("i_price");
temp = Double.parseDouble(price);
total_amount = (total_amount + temp);
amount_total.setText("Php" + total_amount.toString());
add_item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Cart.this,MainActivity.class);
startActivity(intent);
}
});
cartList = (ListView) findViewById(R.id.cart_list);
cartCustomAdapter = new CartCustomAdapter(Cart.this,R.layout.list_cart,cartArray);
cartList.setItemsCanFocus(false);
cartList.setAdapter(cartCustomAdapter);
cartArray.add(new Order(name,price,"1"));
cartCustomAdapter.notifyDataSetChanged();
}
}
Define an interface with method like below to update text view in your activity :
updateDeletedItemCount();
and in this method take integer and increase its count like
deletedCount++;
and then update it on text view like this
tvDeletedCount.setText("Deleted Item Count : "+ deletedCount);
This is the easiest way to do that:
//Add a method to your Cart
public void changeTotal(int totalPrice){
if(textView != null) // set total price
}
// Call after remove an item in your listener:
if(getContext() instanceOf Cart){
((Cart)getContext()).changeTotal(newTotalPrice);
}
This is not the best way, but I think it's ok for now :)

Data fetched from FirebaseDatabase is getting shown in 3 separate AlertDialogs instead of one

I'm fetching some data from FirebaseDatabase and then putting them into an array and then trying to show them in a List which is in a custom AlertDialog.
Here's the code:
query = mDatabase.child("child").child(anotherChild).child("yetAnotherChild");
uProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
query.orderByChild("someChild").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot != null) {
Map<String, String> newD = (Map<String, String>) dataSnapshot.getValue();
ArrayList<String> l = new ArrayList<String>();
l.add(newD.get("lol").substring(30));
String names[] = l.toArray(new String[0]);
AlertDialog.Builder alertDialog = new AlertDialog.Builder(Activity.this);
LayoutInflater inflater = getLayoutInflater();
View convertView = inflater.inflate(R.layout.dialog_list, null);
alertDialog.setView(convertView);
alertDialog.setTitle("title");
ListView lv = (ListView) convertView.findViewById(R.id.lv);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, names);
lv.setAdapter(adapter);
alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
alertDialog.show();
} else {
Toast.makeText(getBaseContext(), "NULLLLL", Toast.LENGTH_SHORT).show();
}
}
...
...
});
}
});
Here's the database structure:
app
-child
-anotherChild
-yetAnotherChild
-inaccessibleChild
-someChild: "value"
-lol: "value"
I can't use valueEventListener() here as I have no access to inaccessibleChild. The inaccessibleChild here is the uid of the other users who followed a particular user. How can I access there uid?
The problem is that data is getting fetched but instead of getting shown in a list in one AlertDialog, it is getting shown one-by-one in 3 separate AlertDialog.
What is going wrong here?
Please let me know.
Firebase transactions are asynchronous so your initial line to add the 3 children happens after you set your listener, therefore your callback is called 3 times. (making 3 dialogs).
Move this line outside of the on click:
query = mDatabase.child("child").child(anotherChild).child("yetAnotherChild");
Then when you add the below listener (inside the on click) it should be ok
query.orderByChild("someChild").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Put limit when you are using valueEventListener or addChildEventListener. like this,
int limit = 100;
databaseRef.child("chats").limitToLast(limit).addValueEventListener(listener);
And always remove listener when you've done with your work related to firebase. like this,
databaseRef.child("chats").limitToLast(limit).removeEventListener(listener);
Thanks.
Create and show the AlertDialog before you call .addChildEventListener()
Then use inside addChildEventListener call notifyDatasetChanged() after you downloaded the appropriate data. Do not create the AlertDialog inside the addChildEventListener
You can use Firebase Queries to limit the data that is downloaded by a listener.
query.orderByChild("someChild").limitToLast(1).addChildEventListener(...
#Blundell has the insight of solving your problem. I just want to suggest you a similar approach with addValueEventListener.
The value event listener will fire once for the initial state of the
data, and then again every time the value of that data changes.
You need to move out the firebase query from onClick function. So your query might look like this..
// Declare the variable names as public
private String names[];
private void addFirebaseListener() {
ref = mDatabase.child("child").child(anotherChild).child("yetAnotherChild");
ref. userRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Map<String, String> newD = (Map<String, String>) dataSnapshot.getValue();
ArrayList<String> l = new ArrayList<String>();
l.add(newD.get("lol").substring(30));
names[] = l.toArray(new String[0]);
// Call notifyDataSetChanged each time your array gets updated
adapter.notifyDataSetChanged();
}
#Override public void onCancelled(FirebaseError error) { }
});
}
Now write a function to show the ListView in the AlertDialog
// Declare the adapter as public and initialize it with null
private ArrayAdapter<String> adapter = null;
private void showListInDialog() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(Activity.this);
LayoutInflater inflater = getLayoutInflater();
View convertView = inflater.inflate(R.layout.dialog_list, null);
alertDialog.setView(convertView);
alertDialog.setTitle("title");
ListView lv = (ListView) convertView.findViewById(R.id.lv);
if(adapter == null)
adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, names);
// Now set the adapter
lv.setAdapter(adapter);
alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
alertDialog.dismiss();
}
});
alertDialog.show();
}
Now inside your onCreate function you need to set the Firebase listener first and then set the onClick function like this.
uProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showListInDialog();
}
});
#Hammad Try this modified code basing on your requirement.
query = mDatabase.child("child").child(anotherChild).child("yetAnotherChild");
AlertDialog alertDialog;
ArrayList<String> l;
uProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
query.orderByChild("someChild").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot != null) {
Map<String, String> newD = (Map<String, String>) dataSnapshot.getValue();
if(l == null) {
l = new ArrayList<String>();
}
l.add(newD.get("lol").substring(30));
String names[] = new String[l.size()];
for(int length=0; length < l.size(); l++) {
names[length] = l.get(length);
}
if(alertDialog == null) {
alertDialog = new AlertDialog.Builder(Activity.this).create();
LayoutInflater inflater = getLayoutInflater();
View convertView = inflater.inflate(R.layout.dialog_list, null);
alertDialog.setView(convertView);
alertDialog.setTitle("title");
ListView lv = (ListView) convertView.findViewById(R.id.lv);
} ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, names);
lv.setAdapter(adapter);
alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
if(!alertDialog.isShowing()) {
alertDialog.show();
}
} else {
Toast.makeText(getBaseContext(), "NULLLLL", Toast.LENGTH_SHORT).show();
}
}
...
...
});
}
});
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildAdded:" + dataSnapshot.getKey());
/**
Retrieve lists of items or listen for additions to a list of items. This callback is triggered once for each existing child and then again every time a new child is added to the specified path. The DataSnapshot passed to the listener contains the new child's data.
**/
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildChanged:" + dataSnapshot.getKey());
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Log.d(TAG, "onChildRemoved:" + dataSnapshot.getKey());
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
Log.d(TAG, "onChildMoved:" + dataSnapshot.getKey());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
ref.addChildEventListener(childEventListener);
Usining ChildEventListener onChildAdded are call per child you have in that node. Means your code runs 3 time so dialog appers 3 time.
This is the problem
So the solution is:
While using a ChildEventListener is the recommended way to read lists of data, there are situations where attaching a ValueEventListener to a list reference is useful.
Attaching a ValueEventListener to a list of data will return the entire list of data as a single DataSnapshot, which you can then loop over to access individual children.
Even when there is only a single match for the query, the snapshot is still a list; it just contains a single item. To access the item, you need to loop over the result:
inaccessibleChild.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) {
//here you can access the each child of that node.
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
// ...
}
});
Well, none of the above answers really helped, though Linxy's answer is correct, I saw it after solving the probelm.
Moving all the code out and writing just this line: alertDialog.show(); inside setOnClickListener() improving my code to this:
query = mDatabase.child("child").child(anotherChild).child("yetAnotherChild");
query.orderByChild("someChild").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot != null) {
Map<String, String> newD = (Map<String, String>) dataSnapshot.getValue();
ArrayList<String> l = new ArrayList<String>();
l.add(newD.get("lol").substring(30));
String names[] = l.toArray(new String[0]);
AlertDialog.Builder alertDialog = new AlertDialog.Builder(Activity.this);
LayoutInflater inflater = getLayoutInflater();
View convertView = inflater.inflate(R.layout.dialog_list, null);
alertDialog.setView(convertView);
alertDialog.setTitle("title");
ListView lv = (ListView) convertView.findViewById(R.id.lv);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1, names);
lv.setAdapter(adapter);
alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
} else {
Toast.makeText(getBaseContext(), "NULLLLL", Toast.LENGTH_SHORT).show();
}
}
...
...
});
uProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
alert11.show();
}
});
Anyway, I would like to thank all those who answered this question.
Peace.

Android Add Listview item dynamically?

i want to add listview item dynamically. i had done this but when i restart the app listview item disappear. How can i save this item permanently to listview. please suggest
public class ChatWithAttorney extends Activity {
ImageView btnBack;
ListView chatList;
EditText etMsg;
Button btnSend;
String msg_to_send;
ArrayAdapter<String> adapter;
ArrayList<String> listMsg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chatwithattorny);
btnBack = (ImageView) findViewById(R.id.btnback);
chatList = (ListView) findViewById(R.id.chatList);
etMsg = (EditText) findViewById(R.id.etMsg);
btnSend = (Button) findViewById(R.id.btnSend);
listMsg = new ArrayList<String>();
adapter = new ArrayAdapter<String>(this, R.layout.chat_list_text, R.id.tvSentMsg,listMsg);
chatList.setAdapter(adapter);
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
try {
msg_to_send = URLEncoder.encode(etMsg.getText().toString(),
"utf-8");
listMsg.add(msg_to_send);
adapter.notifyDataSetChanged();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
}
Put those ArrayList items in a database or SharedPreference and read those items when resuming your activity.
You can use Local database , SharedPreference or Static arraylist for storing the messages
AT the Time of Destroy Serialize the List data.
And Deserilize when Application Starts Again.

Categories

Resources