I have a problem with counting the number of items in ListView.
I'm pushing values into a folder in the firebase database. When I pull them on a separate activity, I get a list of the values I pushed .
The problem is I want to know how many items the list has. I tried to use listView.getCount() and also with arrayList.size() and both show zero, even though in the list itself I do see the values. Why is it happening ?
Here is my Java code:
list = (ListView) findViewById(R.id.listViewId2);
check2 = findViewById(R.id.check3);
arrayList = new ArrayList<String>();
keyList = new ArrayList<String>();
arrayAdapter = new ArrayAdapter<String>(recommendations_weight.this ,android.R.layout.simple_list_item_1,arrayList);
list.setAdapter(arrayAdapter);
mDatabase = FirebaseDatabase.getInstance();
mAuth = FirebaseAuth.getInstance();
mDatabaseReference= FirebaseDatabase.getInstance().getReference().child("Recommendations").child("Blood").child("WBC").child("High").child("Weight").child("1");
mDatabaseReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
String value = dataSnapshot.getValue(String.class);
arrayList.add(value); // include the scan values
keyList.add(dataSnapshot.getKey()); //include the id of each tests
arrayAdapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
//check if we have item
if (list.getAdapter().getCount() != 0){
check2.setText("number");
}
and this is my xml -
<ListView
android:id="#+id/listViewId2"
android:layout_width="350dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:visibility="visible"
android:textAlignment="center" />
<Button
android:id="#+id/returnButton"
android:layout_width="200dp"
android:layout_height="50dp"
android:text="return to test page"
android:textAllCaps="false"
android:background="#60000000"
android:layout_marginTop="30dp"
android:textColor="#FFFFFF"
android:textSize="20dp"
android:layout_gravity="center_horizontal"
/>
<TextView
android:id="#+id/check3"
android:layout_marginTop="19dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="check"
/>
One simply cannot expect the ArrayAdapter to be already populated, when entering asynchronous execution and then instantly checking in a synchronous manner, if there are any items contained.
As your code currently works (or better said: won't work):
at first, it requests remote data (entering asynchronous execution).
then it instantly checks the item-count in the adapter (synchronous execution).
then the items are being added (asynchronous execution).
asynchronous execution finishes.
Asynchronous execution requires callbacks, else you won't know when it had finished.
Just add verbose logging, in order to understand what is going on and in which order.
You're getting 0 because you are checking list.getAdapter().getCount(). I think you want to check whatever list variable holds the data you pass in (I doubt it's adapter).
So maybe: list.getAdapter.getArrayList().getCount()?
Related
I am having a hard time trying to get one of my AutoCompleteTextView to reset based on a selection from another AutoCompleteTextView selection.
Below are the form elements:
The first one is the dropdown for Sport Type:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/sportType"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:hint="Select Sport"
android:labelFor="#+id/sportTypeSelected"
android:background="#EAE7E7">
<AutoCompleteTextView
android:id="#+id/sportTypeSelected"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
android:layout_weight="1"
android:padding="14dp"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
followed by the second on that is Pool Type
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/poolType"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:hint="Select Pool Type"
android:labelFor="#+id/poolTypeSelected"
android:background="#EAE7E7">
<AutoCompleteTextView
android:id="#+id/poolTypeSelected"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
android:layout_weight="1"
android:padding="14dp"
android:textSize="16sp" />
</com.google.android.material.textfield.TextInputLayout>
Here is the Java code that does the work to get the drop down populated:
This is for the Sport Type
So what is happening is the Sport Type drop down will populate on creation of the view:
sportTypeSelected = findViewById(R.id.sportTypeSelected);
List<String> sportsTypes = new ArrayList<>();
sportTypeListener = sportsTypesReference.orderByValue().equalTo("A").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
sportsTypes.clear();
for (DataSnapshot sportSnapshot : dataSnapshot.getChildren()) {
String sportType = sportSnapshot.getKey();
sportsTypes.add(sportType);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
numSportsAdapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, sportsTypes);
sportTypeSelected.setAdapter(numSportsAdapter);
For the Pool Type, is not preloaded based on the hiding of the drop down.
Then based on the selection of the Sport Type, the setOnItemClickListener will trigger the Pool Type to populate
poolTypeSelected = findViewById(R.id.poolTypeSelected);
List<String> poolTypes = new ArrayList<>();
// HIDE THE DROPDOWN
poolTypeSelected.setDropDownHeight(0); <-- Hide the drop down init
poolTypeSelected.setDropDownWidth(0); <-- Hide the drop down init
sportTypeSelected.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick (AdapterView<?> parent, View view, int position, long id) {
// Enable
poolTypeSelected.setDropDownHeight(ConstraintLayout.LayoutParams.WRAP_CONTENT);
poolTypeSelected.setDropDownWidth(ConstraintLayout.LayoutParams.MATCH_PARENT);
poolTypeListener = poolTypesReference.child(sportTypeSelected.getText().toString()).orderByValue().equalTo("A").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
poolTypes.clear();
for (DataSnapshot sportSnapshot : dataSnapshot.getChildren()) {
String pTypes = sportSnapshot.getKey();
poolTypes.add(pTypes);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
});
numPoolsAdapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, poolTypes);
poolTypeSelected.setAdapter(numPoolsAdapter);
My issue is that I would like for the Pool Type to get blanked out/reset every time the selection changes in the Sport Type dropdown as the choices could change.
Can someone please let me know how I can achieve this!?
Update:
If I use:
poolTypeSelected.setText("");
the rest of my Firebase lookup wont populate and I land up with a blank dropdown.
I'll assume that its a timing issue and the setText("") is removing the entires retrieved by the Firebase lookup.
I have the problem, Fragment has content and I want to add simple ProgressBar while of Firebase loading content. How can I do this and where ? (I try to add in onDataChange but it dosn't work, code below)
public void onDataChange(DataSnapshot dataSnapshot) {
progressBar.setVisibility(View.VISIBLE);
mContentLayout.setVisibility(LinearLayout.GONE);
for (final DataSnapshot snapshot : dataSnapshot.getChildren()) {
item = snapshot.getValue(Item.class);
if(item.isSales()) {
arrayOfItemProduct.add(item);
}
}
adapter.notifyDataSetChanged();
progressBar.setVisibility(View.GONE);
mContentLayout.setVisibility(LinearLayout.VISIBLE);
}
To sovle this, you can add in your .XML layout file of your fragment the following lines of code:
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/progress_bar"
android:layout_centerInParent="true"
style="#style/Widget.AppCompat.ProgressBar"/>
This means that everytime you start your fragment the ProgressBar will show up.
Define the progressBar variable as a global variable and then find it in your fragmnet inside the onCreateView() method like this:
progressBar = yourFragmentView.findViewById(R.id.progress_bar);
And then inside your onDataChange() method use the following code:
if (progressBar != null) {
progressBar.setVisibility(View.GONE);
}
I have an EditText and when I set it to Empty and Click on my Button, my App crashes.
When I view it in Android Monitor it points to the line:
final int addTm = Integer.parseInt(Teaching);
Here is my code:
LinearLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="2dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:text="" />
<EditText
android:id="#+id/tM"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginRight="50dp"
android:ems="1"
android:inputType="number"
android:maxLength="1"
android:text="0" />
<Button
android:id="#+id/submitBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit" />
</LinearLayout>
And my Java Code:
Submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String Teaching = Tm.getText().toString();
final int addTm = Integer.parseInt(Teaching);
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("sub").child("TM");
myRef.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
Integer currentValue = mutableData.getValue(Integer.class);
if (currentValue == null) {
mutableData.setValue(0);
} else {
mutableData.setValue(currentValue + addTm);
}
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean committed, DataSnapshot dataSnapshot) {
System.out.println("Transaction completed");
}
});
}
});
The other answers are good, but I'd recommend wrapping with a try/catch for the NumberFormatException. I know you have the input set to accept numbers only, but always better safe than sorry.
Lowercase the String variable Teaching. In Java we only upper case Type names. (classes, interfaces, etc.) Notice how StackOverflow is highlighting the variable Teaching blue, a bit disorienting no?
Do this for your member fields as well Tm and Submit. They should be written tm and submit. Also, Tm is not a very descriptive name for a variable either. Imagine another programmer coming in and looking at your code, and wondering what a tm is. What is the context of this tm, where does it come from... what does it do? Is it a Teenage Mutant?
Regardless when using Integer.parseInt wrap it in a try/catch:
#Override
public void onClick(View view){
final int addTm;
try {
String teaching = Tm.getText().toString();
addTm = Integer.parseInt(teaching);
} catch (NumberFormatException e) {
addTm = 0;
}
// ...
}
Why should you do this? What if I enter a decimal number into your number input?
Using your accepted answer you will still crash. Integer.parseInt does not parse decimal numbers.
Or how about, if I switch the locale of the device and enter a number with odd characters that Integer.parseInt won't expect.
Gotta catch that exception to be full proof.
When executing Integer.parseInt() on an empty string it throws an NumberFormatException.
First, check the value of Teaching, and verify it's not empty string, or - try/catch for NumberFormatException, and set the value you want for Teaching in that case.
Can someone help with this? My EditText is not empty but the toast still shows up. My app require users to select Date and Time, then select 1 item on the listview to proceed. A dialog will pop out after that. However for some reason, even though my edittext isn't empty, it still won't allow me to continue. I can't seem to figure out what's wrong, I mean the code is just that simple, nothing complicate.
final String date = textDate1.getText().toString().trim();
final String time = textTime1.getText().toString().trim();
listViewHistory.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
final Team team = teams.get(i);
if(TextUtils.isEmpty(date)){
Toast.makeText(RecreateActivity.this,"Please choose a date.",Toast.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(time)){
Toast.makeText(RecreateActivity.this,"Please choose a time.",Toast.LENGTH_LONG).show();
return;
}
//the rest of the code
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(RecreateActivity.this);
LayoutInflater inflater = getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.confirm_layout, null);
dialogBuilder.setView(dialogView);
final Button buttonYes2 = (Button) dialogView.findViewById(R.id.buttonYes2);
final Button buttonNo2 = (Button) dialogView.findViewById(R.id.buttonNo2);
//final Team team = teams.get();
final AlertDialog b = dialogBuilder.create();
b.show();
buttonYes2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
databaseMembers.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final ArrayList<String> CheckList = new ArrayList<String>();
for (DataSnapshot check : dataSnapshot.child("teams").getChildren()) {
CheckList.add(check.getKey());
}
if (CheckList.contains(team.getTeamName())) {
Toast.makeText(RecreateActivity.this, "Team already exist.", Toast.LENGTH_LONG).show();
return;
}
databaseMembers.child("History").child(team.getTeamName()).child("date").setValue(date);
databaseMembers.child("History").child(team.getTeamName()).child("time").setValue(time);
for (DataSnapshot history : dataSnapshot.child("History").child(encodedEmailAddress).getChildren()) {
String key = history.getKey();
if (key.equals(team.getTeamName())) {
teams.clear();
Team team = history.getValue(Team.class);
teams.add(team);
databaseTeams.child(team.getTeamName()).setValue(team);
}
if (key.equals("teamMember")) {
for (DataSnapshot members : dataSnapshot.child("History").child(encodedEmailAddress).child("teamMember").getChildren()) {
String key2 = members.getKey();
String value = members.getValue(String.class);
Map<String, Object> map = new HashMap<>();
map.put(key2, value);
databaseMembers.child("members").child(team.getTeamName()).child("teamMember").updateChildren(map);
b.dismiss();
}
}
}
Toast.makeText(RecreateActivity.this, "Team created.", Toast.LENGTH_LONG).show();
Intent myIntent = new Intent(RecreateActivity.this,
MainActivity.class);
startActivity(myIntent);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
}
XML:
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Previous Team"
android:textAppearance="#style/TextAppearance.AppCompat.Title"
android:textAlignment="center"/>
<TextView
android:id="#+id/textView3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Select new Date/Time and tap on the Team."
android:textAlignment="center"/>
<ListView
android:id="#+id/listViewHistory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
</ListView>
<TextView
android:id="#+id/textView5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Members:"
android:textAppearance="#style/TextAppearance.AppCompat.Headline" />
<TextView
android:id="#+id/textViewList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textAppearance="#style/TextAppearance.AppCompat.Medium" />
<EditText
android:id="#+id/textDate1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Select Date..."
android:layout_alignParentStart="true" />
<EditText
android:id="#+id/textTime1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Select Time..."
android:layout_below="#+id/textDate"
android:layout_alignParentStart="true" />
<Button
android:id="#+id/buttonAddHistory"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Create Team"
android:textAlignment="center"
android:textAllCaps="false"
tools:textSize="20sp" />
You are getting string from EditText only once - before setting OnItemClickListener. You need to get string inside the listener.
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
final Team team = teams.get(i);
final String date = textDate1.getText().toString().trim();
final String time = textTime1.getText().toString().trim();
if(TextUtils.isEmpty(date)){
Toast.makeText(RecreateActivity.this,"Please choose a date.",Toast.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(time)){
Toast.makeText(RecreateActivity.this,"Please choose a time.",Toast.LENGTH_LONG).show();
return;
}
}
Your field is initialized only once. I don't know the context, this may be actually what you want, but then it doesn't make any sense to validate it every time, those fields have the same value every time the listener code is run. Try to add the code to get date and time in the listener itself.
Your code is setting [date] and [time] outside of the onClickListener. When the user clicks the button, your code isn't resetting the variables. I'd evaluate the EditText directly from your onClickListener code:
listViewHistory.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
final Team team = teams.get(i);
if(TextUtils.isEmpty(textDate1.getText().toString().trim())){
Toast.makeText(RecreateActivity.this,"Please choose a date.",Toast.LENGTH_LONG).show();
return;
}
if(TextUtils.isEmpty(textTime1.getText().toString().trim())){
Toast.makeText(RecreateActivity.this,"Please choose a time.",Toast.LENGTH_LONG).show();
return;
}
Try getting date value of edittext inside the click listener.
listViewHistory.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
final Team team = teams.get(i);
final String date = textDate1.getText().toString().trim();
final String time = textTime1.getText().toString().trim();
if(date.isEmpty()){
Toast.makeText(RecreateActivity.this,"Please choose a date.",Toast.LENGTH_LONG).show();
return;
}
if(time.isEmpty()){
Toast.makeText(RecreateActivity.this,"Please choose a time.",Toast.LENGTH_LONG).show();
return;
}
I'm trying to do my first Spinner, and I have encountered some difficulties, such as that I don't know if I can get an option by spinner.getSelectItem == "some string".
Take a look at my code so far
Populating the spinner:
public void addItemsOnSpinner() {
Spinner buttonSpinner = (Spinner) findViewById(R.id.buttonSpinner);
List<String> list = new ArrayList<String>();
list.add("Ultimos 5 lancamentos");
list.add("Ultimos 7 lancamentos");
list.add("Ultimos 10 lancamentos");
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
buttonSpinner.setAdapter(dataAdapter);
}
Trying to make an if statement:
if(buttonSpinner.getSelectedItem().toString() == "Ultimos 10 lancamentos"){
textView.setVisibility(View.VISIBLE);
}
TextView code as requested:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Deposito"
android:visibility="invisible"
android:id="#+id/textView"
android:layout_row="2"
android:layout_column="0"
android:layout_gravity="center|left" />
And its code on the class:
TextView textView = (TextView)findViewById(R.id.textView);
Yes you can do it and it will work fine, but please use
buttonSpinner.getSelectedItem().toString().equals("Ultimos 10 lancamentos");
As Stefano has pointed out, your comparison should be using equals (which compares the String contents, vs == which compares the object references).
Otherwise your if statement should work, however its not clear where you are calling it from (and that might be the cause of the problem). If you want to make the comparison immediately after a spinner item is selected then you need to set an OnItemSelectedListener and make the comparison there.
Here is an example of how you might declare this listener inline:
buttonSpinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener()
{
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
String selectedItem = parent.getSelectedItem().toString();
if (selectedItem.equals("Ultimos 10 lancamentos"))
{
textView.setVisibility(View.VISIBLE);
}
}
public void onNothingSelected(AdapterView<?> parent)
{
}
});