I'm trying to get the values from a recyclerView item (Firestore as database) in a new activity by using intents if I click on it. Don't know if that is the best way, but I got so far.
In my second activity I only get Null in the textViews I want to populate.
I've tried to test it with Toasts. You will see there is two Toast messages. The first one in the mainActivity (UltraLiquors) show the data I want to pull correctly (the ID, product and price), but the second one in the details activity only shows "null", so I assume there is a problem with my getExtras in my detail activity. I just don't know where to look anymore.
Please be so kind and help, I really have been struggling with this a few days.
Here is my mainActivity (UltraLiquors.class)
public class UltraLiquors extends AppCompatActivity {
private FirebaseFirestore ultra_liquor_db = FirebaseFirestore.getInstance();
private CollectionReference promo_oneRef = ultra_liquor_db.collection("ultra_liquors");
private static final int ACTIVITY_NUM = 2;
private UltraLiquorsRecyclerAdapter ultra_liquors_adapter;
private static final String TAG = "Ultra Liquors";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ultra_liquors);
setUpPromoOneRecyclerView();
//setupBottomNavigationView();
setTitle("Ultra Liquors");
Context context;
}
private void setUpPromoOneRecyclerView() {
Query query = promo_oneRef.whereEqualTo("promo_number", "1").orderBy("department");
FirestoreRecyclerOptions<Ultra_liquors> options = new FirestoreRecyclerOptions.Builder<Ultra_liquors>()
.setQuery(query, Ultra_liquors.class)
.build();
ultra_liquors_adapter = new UltraLiquorsRecyclerAdapter(options);
RecyclerView promo_one_recyclerView = findViewById(R.id.recycler_view_ultra_liquors);
//recyclerView.setHasFixedSize(true);
promo_one_recyclerView.setLayoutManager(new LinearLayoutManager(this));
promo_one_recyclerView.setAdapter(ultra_liquors_adapter);
ultra_liquors_adapter.setOnItemClickListener(new UltraLiquorsRecyclerAdapter.OnItemClickListener() {
#Override
public void onItemClick(DocumentSnapshot documentSnapshot, int position) {
Ultra_liquors note = documentSnapshot.toObject(Ultra_liquors.class);
String id = documentSnapshot.getId();
String product = (String) documentSnapshot.get("product");
String price = (String) documentSnapshot.get("price");
String path = documentSnapshot.getReference().getPath();
Toast.makeText(UltraLiquors.this,
"Position: " + position + " ID: " + product + price, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(UltraLiquors.this, ViewProduct.class);
intent.putExtra("Product", product);
intent.putExtra("Price", price);
startActivity(intent);
}
});
}
#Override
protected void onStart() {
super.onStart();
ultra_liquors_adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
ultra_liquors_adapter.stopListening();
}
}
And here is the detailActivity (ViewProduct) where I want to pull the data from the intent:
public class ViewProduct extends AppCompatActivity {
private String edit_product_ID;
//private String edit_product_Product;
private String edit_product_Price;
private TextView productView, priceView;
private TextView mSave, mDelete;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_product);
Intent intent = getIntent();
String product;
String price;
product = String.valueOf(getIntent().getExtras().get("product"));
price = String.valueOf(getIntent().getExtras().get("price"));
Toast.makeText(this, "The Product ID: " + edit_product_ID +
" Product Name " + product + " Product Price " + price, Toast.LENGTH_LONG).show();
TextView productView = findViewById(R.id.product);
productView.setText(product);
TextView priceView = findViewById(R.id.price);
priceView.setText(price);
mSave = (TextView) findViewById(R.id.save);
mDelete = (TextView) findViewById(R.id.delete);
}}
I am not the best yet with Java or Android, so please be patient.
You're using:
intent.putExtra("Product", product);
intent.putExtra("Price", price);
But then you're trying to get them with:
product = String.valueOf(getIntent().getExtras().get("product"));
price = String.valueOf(getIntent().getExtras().get("price"));
See how these values are different ?
You need to use the same casing, as it's case sensitive, so use something like:
product = String.valueOf(getIntent().getExtras().get("Product"));
price = String.valueOf(getIntent().getExtras().get("Price"));
Related
I have a form where a person can enter details about a friend (name, age, gender, address). This friend is displayed in a list view and when a friend from the list is clicked on they have the choice to edit that record.
I can successfully update every detail about a friend except for the gender.
For example:
List view:
1) James Bond, 20, Male, Sydney NSW
Then I click edit and change it to
James smith, 21, Female, Canberra NSW
and then back in my list view it will show:
1) James smith, 21, Male, Canberra NSW
Notice how the gender doesn't change?
I can figure out why this is happening as I use the same logic to change the name and age as i did to change the gender
Here is the relevant code:
ViewFriend.java ( this class displays the list view and has the edit option)
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view, final int position, long id) {
String text = listView.getItemAtPosition(position).toString();
final int ID = Integer.parseInt(String.valueOf(text.charAt(0)));
AlertDialog.Builder builder = new AlertDialog.Builder(viewFriends.this);
builder.setTitle("Notice");
builder.setMessage("Please select to to edit, delete a friend or cancel");
// add the buttons
builder.setPositiveButton("Edit", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(getApplicationContext(), editOrDelete.class);
ArrayList<String> result1 = mydb.retrieveRow(ID);
name = result1.get(1);
age = result1.get(2);
gender = result1.get(3);
address = result1.get(4);
code = result1.get(0);
intent.putExtra("code", code);
intent.putExtra("name", name);
intent.putExtra("age", age);
intent.putExtra("gender", gender);
intent.putExtra("address", address);
startActivity(intent);
}
});
builder.setNeutralButton(" Delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
mydb.deleteTitle(ID);
finish();
Intent intent = new Intent(getApplicationContext(),viewFriends.class);
startActivity(intent);
}
});
builder.setNegativeButton("Cancel", null);
AlertDialog dialog = builder.create();
dialog.show();
}
});
The code above retrieves the details from the database and passes it to the intent. I have printed the contents of each variable (name, age, gender, address) and they print out correctly.
editFriend.java ( this class pre fills the form with the data passed through the intent that displays correctly)
public class editFriend extends AppCompatActivity {
private Intent intent;
private RadioGroup rg;
private Button update;
private RadioButton rb;
private String newName,newAddress,newGender;
private int newAge;
EditText ed, ed1;
public String name,address,gender,age,code;
private int selectedID,ages,codes;
NumberPicker numberPicker;
private databaseManager4 myDataBase;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_editordeletefriend);
intent= getIntent();
myDataBase = new databaseManager4(this);
rg = (RadioGroup)findViewById(R.id.radioGroup_update);
selectedID = rg.getCheckedRadioButtonId();
rb = (RadioButton) findViewById(selectedID);
ed = (EditText)findViewById(R.id.fullName_update);
numberPicker = (NumberPicker)findViewById(R.id.resultAge_update);
numberPicker.setMinValue(6);
numberPicker.setMaxValue(110);
numberPicker.setWrapSelectorWheel(false);
update = (Button)findViewById(R.id.update_button);
ed1 = (EditText)findViewById(R.id.address_update);
name = intent.getStringExtra("name");
age = intent.getStringExtra("age");
gender = intent.getStringExtra("gender");
address = intent.getStringExtra("address");
code = intent.getStringExtra("code");
codes = Integer.parseInt(code);
displayForm();
newName = ed.getText().toString();
newAge = numberPicker.getValue();
newGender = rb.getText().toString();
update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int id = rg.getCheckedRadioButtonId();
rb = (RadioButton) findViewById(id);
if (myDataBase.updateRow(codes,newName,newAge,newGender,ed1.getText().toString())){
Toast.makeText(getApplicationContext(),"successfully updated the friend "
+ed.getText().toString(),Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(),"Could not update the friend "
+ed.getText().toString(),Toast.LENGTH_SHORT).show();
}
intent = new Intent(getApplicationContext(),viewFriends.class);
startActivity(intent);
}
});
}
public void displayForm(){
ed.setText(name);
ed1.setText(address);
if (gender.equals("Male")){
rb = (RadioButton)findViewById(R.id.resultGenderMale_update);
}
else if (gender.equals("Female"))
{
rb = (RadioButton)findViewById(R.id.resultGenderFemale_update);
}
rb.setChecked(true);
ages= Integer.parseInt(age);
numberPicker.setValue(ages);
}
public void clear(){
ed.setText("");
ed1.setText("");
}
}
This is where the issue lies, even if the user clicks on Male it registers as female and i am unsure why.
Any ideas how i can fix this?
Your problem is that you set value of rb variable to a single radio button, predefined with previous gender value here
if (gender.equals("Male")){
rb = (RadioButton)findViewById(R.id.resultGenderMale_update);
}
else if (gender.equals("Female"))
{
rb = (RadioButton)findViewById(R.id.resultGenderFemale_update);
}
And you read value of the same button then. To fix that in you click listener for update button you need to read checked radio button id using getCheckedRadioButtonId on radio group (your rg variable).
upd:
this is how your Edit Friend activity code might look like
public class EditFriendActivity extends AppCompatActivity {
private RadioGroup mGenderRadioGroup;
private Button mUpdateButton;
private EditText mNameField;
private EditText mAddressField;
private NumberPicker mAgePicker;
private databaseManager4 mDatabaseManager;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_editordeletefriend);
initUI();
mDatabaseManager = new databaseManager4(this);
}
private void initUI() {
Intent intent = getIntent();
mNameField = (EditText) findViewById(R.id.fullName_update);
mNameField.setText(intent.getStringExtra("name"));
mAddressField = (EditText) findViewById(R.id.address_update);
mAddressField.setText(intent.getStringExtra("address"));
mAgePicker = (NumberPicker) findViewById(R.id.resultAge_update);
mAgePicker.setMinValue(6);
mAgePicker.setMaxValue(110);
mAgePicker.setWrapSelectorWheel(false);
mAgePicker.setValue(Integer.parseInt(intent.getStringExtra("age")));
mUpdateButton = (Button) findViewById(R.id.update_button);
mUpdateButton.setOnClickListener(updateClickListener);
mGenderRadioGroup = (RadioGroup) findViewById(R.id.radioGroup_update);
RadioButton targetRadioButton = null;
switch (Gender.fromString(intent.getStringExtra("gender"))) {
case MALE:
targetRadioButton = (RadioButton) findViewById(R.id.resultGenderMale_update);
break;
case FEMALE:
targetRadioButton = (RadioButton) findViewById(R.id.resultGenderFemale_update);
break;
}
if (targetRadioButton != null) {
targetRadioButton.setChecked(true);
}
}
public void clear() {
mNameField.setText("");
mAddressField.setText("");
}
private Gender getSelectedGender() {
int checkedButtonId = mGenderRadioGroup.getCheckedRadioButtonId();
switch (checkedButtonId) {
case R.id.resultGenderMale_update:
return Gender.MALE;
case R.id.resultGenderFemale_update:
return Gender.FEMALE;
}
return Gender.UNDEFINED;
}
private View.OnClickListener updateClickListener =
new View.OnClickListener() {
#Override
public void onClick(View v) {
Gender newGender = getSelectedGender();
int code = Integer.parseInt(getIntent().getStringExtra("code"));
System.out.println("gender is" + newGender.stringValue);
if (mDatabaseManager.updateRow(
code,
mNameField.getText().toString(),
mAgePicker.getValue(),
newGender.stringValue,
mAddressField.getText().toString())) {
Toast.makeText(
getApplicationContext(),
"successfully updated the friend " + ed.getText().toString(),
Toast.LENGTH_SHORT)
.show();
} else {
Toast.makeText(
getApplicationContext(),
"Could not update the friend " + ed.getText().toString(),
Toast.LENGTH_SHORT)
.show();
}
Intent viewFriendsIntent = new Intent(getApplicationContext(), viewFriends.class);
startActivity(viewFriendsIntent);
finish();
}
};
private enum Gender {
UNDEFINED("undefined"),
MALE("Male"),
FEMALE("Female");
private #Nullable String stringValue;
Gender(#Nullable String stringValue) {
this.stringValue = stringValue;
}
public static Gender fromString(#Nullable String value) {
if (value != null) {
for (Gender gender : Gender.values()) {
if (value.equals(gender.stringValue)) {
return gender;
}
}
}
return UNDEFINED;
}
}
}
I am struggling to make a tie between my users in Firebase, and data that I want it to be linked to.
At the moment I am able to create users and log in with users credentials. Additionally, I am able to create Maintenance Issues using my MaintenanceActivity.
However, when I log in with an arbitrary user, the same maintenance issues will always show.
I am unsure how to link the User ID of each user to a maintenance issue, so that when a user logs in only their maintenance issues will show.
Totally unsure on where to start here, so any help would be much appreciated. Been struggling with this for a few days.
SignUpActivity
This creates users in the 'Users' table in my Firebase database, but I also want it to contain the User ID which can be linked to maintenance issues.
mDatabase = FirebaseDatabase.getInstance().getReference().child("users");
final DatabaseReference[] ref = new DatabaseReference[1];
final FirebaseUser[] mCurrentUser = new FirebaseUser[1];
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(SignUpActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
Toasty.info(getApplicationContext(), "creation of account was: " + task.isSuccessful(), Toast.LENGTH_SHORT).show();
if (task.isSuccessful()) {
mCurrentUser[0] = task.getResult().getUser();
ref[0] =mDatabase.child(mCurrentUser[0].getUid());
ref[0].child("email").setValue(email);
Intent intent = new Intent(SignUpActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
}
});
MaintenanceActvity
public class MaintenanceActivity extends AppCompatActivity {
EditText editTextTitle;
EditText editTextDesc;
Spinner spinnerPrimary;
Spinner spinnerSecondary;
Spinner spinnerProperty;
Button buttonSubmit;
DatabaseReference databaseMaintenance;
ListView listViewIssues;
List<Maintenance> maintenanceList;
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference fDatabaseRoot = database.getReference();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maintenance);
Toolbar toolbar = (Toolbar) findViewById(R.id.actionBar);
setSupportActionBar(toolbar);
ActionBar ab = getSupportActionBar();
ab.setDisplayHomeAsUpEnabled(true);
databaseMaintenance = FirebaseDatabase.getInstance().getReference("maintenance");
editTextTitle = (EditText) findViewById(R.id.editTextTitle);
editTextDesc = (EditText) findViewById(R.id.editTextDesc);
buttonSubmit = (Button) findViewById(R.id.buttonSubmit);
spinnerPrimary = (Spinner) findViewById(R.id.spinnerPrimary);
spinnerSecondary = (Spinner) findViewById(R.id.spinnerSecondary);
spinnerProperty = (Spinner) findViewById(R.id.spinnerProperty);
listViewIssues = (ListView) findViewById(R.id.listViewIssues);
maintenanceList = new ArrayList<>();
buttonSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addMaintenance();
}
});
listViewIssues.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Maintenance maintenance = maintenanceList.get(position);
showMoreInfoDialog(maintenance.getMaintenanceId(), maintenance.getMaintenanceTitle(), maintenance.getMaintenanceDescription(), maintenance.getMaintenancePrimary(), maintenance.getMaintenanceSecondary(), maintenance.getMaintenanceProperty());
return false;
}
});
}
#Override
protected void onStart() {
super.onStart();
databaseMaintenance.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
maintenanceList.clear();
for(DataSnapshot maintenanceSnapshot : dataSnapshot.getChildren()){
Maintenance maintenance = maintenanceSnapshot.getValue(Maintenance.class);
maintenanceList.add(maintenance);
}
MaintenanceList adapter = new MaintenanceList (MaintenanceActivity.this, maintenanceList);
listViewIssues.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
fDatabaseRoot.child("properties").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Is better to use a List, because you don't know the size
// of the iterator returned by dataSnapshot.getChildren() to
// initialize the array
final List<String> propertyAddressList = new ArrayList<String>();
for (DataSnapshot addressSnapshot: dataSnapshot.getChildren()) {
String propertyAddress = addressSnapshot.child("propertyAddress").getValue(String.class);
if (propertyAddress!=null){
propertyAddressList.add(propertyAddress);
}
}
Spinner spinnerProperty = (Spinner) findViewById(R.id.spinnerProperty);
ArrayAdapter<String> addressAdapter = new ArrayAdapter<String>(MaintenanceActivity.this, android.R.layout.simple_spinner_item, propertyAddressList);
addressAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinnerProperty.setAdapter(addressAdapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void showMoreInfoDialog(final String id, String maintenanceTitle, String maintenanceDescription, String maintenancePrimary, String maintenanceSecondary, String maintenanceProperty) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
final View dialogView = inflater.inflate(R.layout.more_info_dialog, null);
dialogBuilder.setView(dialogView);
final EditText editTextTitle = (EditText) dialogView.findViewById(R.id.editTextTitle);
final EditText editTextDesc = (EditText) dialogView.findViewById(R.id.editTextDesc);
final Button buttonUpdate = (Button) dialogView.findViewById(R.id.buttonUpdate);
final Spinner spinnerPrimary = (Spinner) dialogView.findViewById(R.id.spinnerPrimary);
final Spinner spinnerSecondary = (Spinner) dialogView.findViewById(R.id.spinnerSecondary);
final Spinner spinnerProperty = (Spinner) dialogView.findViewById(R.id.spinnerProperty);
final Button buttonDelete = (Button) dialogView.findViewById(R.id.buttonDelete);
dialogBuilder.setTitle("Updating Maintenance " + maintenanceTitle);
final AlertDialog alertDialog = dialogBuilder.create();
alertDialog.show();
buttonUpdate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String title = editTextTitle.getText().toString().trim();
String desc = editTextDesc.getText().toString().trim();
String primary = spinnerPrimary.getSelectedItem().toString();
String secondary = spinnerSecondary.getSelectedItem().toString();
String property = spinnerProperty.getSelectedItem().toString();
if(TextUtils.isEmpty(title)){
editTextTitle.setError("Title Required");
return;
}
updateMaintenance(title, desc, id, primary, secondary, property);
alertDialog.dismiss();
}
});
private boolean updateMaintenance(String title, String desc, String id, String primary, String secondary, String property) {
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("maintenance").child(id);
Maintenance maintenance = new Maintenance (id, title, desc, primary, secondary, property);
databaseReference.setValue(maintenance);
Toast.makeText(this, "Maintenance Updated Updated Successfully", Toast.LENGTH_LONG).show();
return true;
}
private void addMaintenance(){
String title = editTextTitle.getText().toString().trim();
String desc = editTextDesc.getText().toString().trim();
String primary = spinnerPrimary.getSelectedItem().toString();
String secondary = spinnerSecondary.getSelectedItem().toString();
String property = spinnerProperty.getSelectedItem().toString();
if(!TextUtils.isEmpty(title)){
String id = databaseMaintenance.push().getKey();
Maintenance maintenance = new Maintenance (id, title, desc, primary, secondary, property);
databaseMaintenance.child(id).setValue(maintenance);
Toast.makeText(this, "Maintenance Added", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "You must enter a maintenance record", Toast.LENGTH_LONG).show();
}
}
}
Firebase Database
Database Rules are as follows:
{
"rules": {
"users": {
"$uid": {
".write": "$uid === auth.uid",
".read": "$uid === auth.uid"
}
}
}
}
A basic approach that u can take is have a User Id for every maintenance node that you push.
So as per your firebase database you have a user ID "bfPG...."
This id can be the parent node for every maintenance record.
If you change this line to this
String id = databaseMaintenance.push().getKey();
this
String id = FirebaseAuth.getInstance().getCurrentUser().getUID(); //Check Syntax
you'll be pushing a maintenance record under a user ID and you can then differentiate maintenance records with different users.
Thus in order to get the records for a specific user you have to change your firebase query.
databaseMaintenance = FirebaseDatabase.getInstance().getReference("maintenance").orderByKey().equalTo(id);
https://firebase.google.com/docs/database/android/lists-of-data
check the link about how to filter records.
Another approach is you have an adapter to which you are adding maintenance records so before you add a record you can check if it belongs to the current user or not and add records accordingly.
I am attempting to pull data from Firebase Database into a RecyclerView and properly order them. I am successfully getting the data into the recyclerview but the ordering is wrong.
What I am getting:
Android Screenshot
Essentially it's ordering them:
Small
Enterprise
Large
Micro
Medium
My Firebase DB
It orders like this in the app MOST of the time, although one time it ordered correctly which leaves me to believe it is somewhat random depending on which task is finishing first.
I had originally looked up ordering of arraylist(How to sort ArrayList<Long> in Java in decreasing order?) and then ordering of firebase(https://firebase.google.com/docs/database/android/lists-of-data#sort_data) and wasn't sure if there is something else I'm missing?
How is the combination of the asynchronous onDataChange and the Callback decide which finishes first? It's not doing it in the order I have them in the code.
I would like them to be ordered by lowest price first, so:
Micro
Small
Medium
Large
Enterprise
Here is my code:
RegisterSubscriptionActivity.java:
public class RegisterSubscriptionActivity extends Activity {
//Firebase Database References
DatabaseReference mDatabase;
DatabaseReference mDatabaseMicro;
DatabaseReference mDatabaseSmall;
DatabaseReference mDatabaseMedium;
DatabaseReference mDatabaseLarge;
DatabaseReference mDatabaseEnterprise;
DatabaseReference mListItemRef;
ArrayList subscriptionInfo;
//Subscription (String) values
String name, number, price;
//RECYCLERVIEW ITEMS
private Context mContext;
LinearLayout mLinearLayout;
private RecyclerView mRecyclerView;
private MyAdapterSubscription mAdapter = new MyAdapterSubscription(this);
private RecyclerView.LayoutManager mLayoutManager;
//ArrayList<LinearLayout> linearLayoutList = new ArrayList<LinearLayout>();
ArrayList<Subscription> myListItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register_subscription);
myListItems = new ArrayList<Subscription>();
//CALLBACK SO YOU CAN GET THE DATA (FROM) THE ASYNC CALL AND USE IT OUTSIDE OF THE CALL, OTHERWISE IT WILL SHOW AS NULL
final DataSnapshotCallback callback = new DataSnapshotCallback() {
#Override
public void gotDataSnapshot(DataSnapshot snapshot) {
Subscription subscription = new Subscription(snapshot);
myListItems.add(subscription);
mAdapter.updateDataSet(myListItems);
Log.i("ARRAY LIST CONTENTS", myListItems.get(0).getName());
Log.i("DATA","Name: " + subscription.getName() + " Price: " + subscription.getPrice() + " Number: " + subscription.getNumber());
}
};
mDatabase = FirebaseDatabase.getInstance().getReference("Subscription");
mDatabaseMicro = mDatabase.child("Micro");
mDatabaseSmall = mDatabase.child("Small");
mDatabaseMedium = mDatabase.child("Medium");
mDatabaseLarge = mDatabase.child("Large");
mDatabaseEnterprise = mDatabase.child("Enterprise");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
callback.gotDataSnapshot(dataSnapshot); //CALLS THE CALLBACK AND SENDS THE DATASNAPSHOT TO IT
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d("Cancelled",databaseError.toString());
}
}; //END of ValueEventListener
mDatabaseMicro.addListenerForSingleValueEvent(eventListener);
mDatabaseSmall.addListenerForSingleValueEvent(eventListener);
mDatabaseMedium.addListenerForSingleValueEvent(eventListener);
mDatabaseLarge.addListenerForSingleValueEvent(eventListener);
mDatabaseEnterprise.addListenerForSingleValueEvent(eventListener);
//Log.i("DATA ITEMS", "NAME: " + name + " / " + "NUMBER: " + number + " / " + "PRICE: " + price); //Will get Null because not in Callback
//Log.i("LIST OF DATA: ", myListItems.toString()); //Same
//RECYCLERVIEW STUFF
mRecyclerView = (RecyclerView) findViewById(R.id.s_recycler_view);
mContext = getApplicationContext(); // Get the application context
// Define a layout for RecyclerView
mLayoutManager = new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(mLayoutManager);
// Set the adapter for RecyclerView
mRecyclerView.setAdapter(mAdapter);
} //END OF ONCREATE
interface DataSnapshotCallback {
void gotDataSnapshot(DataSnapshot snapshot);
}
}
Subscription.java:
public class Subscription {
String name, number;
Long price;
public Subscription(DataSnapshot dataSnapshot) {
name = dataSnapshot.child("name").getValue(String.class);
number = dataSnapshot.child("number").getValue(String.class);
price = dataSnapshot.child("price").getValue(Long.class);
}
public String getName() {
return name;
}
public String getNumber() {
return number;
}
public Long getPrice() {
return price;
}
}
MyAdapterSubscription.java:
class MyAdapterSubscription extends RecyclerView.Adapter<MyAdapterSubscription.ViewHolder> {
private ArrayList<Subscription> mDataSet = new ArrayList<>();
private Context mContext;
MyAdapterSubscription(Context context){
mContext = context;
}
static class ViewHolder extends RecyclerView.ViewHolder{
TextView nameTV, numberTV, priceTV;
ViewHolder(View v){
super(v);
nameTV = (TextView) v.findViewById(R.id.subNameTV);
numberTV = (TextView) v.findViewById(R.id.subNumberTV);
priceTV = (TextView) v.findViewById(R.id.subPriceTV);
}
}
void updateDataSet(ArrayList<Subscription> myArrayList) {
mDataSet = myArrayList;
// TODO: 12/13/2017 Sort array list by price. Lowest to highest.
//Collections.sort(mDataSet);
// TODO: 12/14/2017 Let it be clickable and link to payment
notifyDataSetChanged();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
// Create a new View
View v = LayoutInflater.from(mContext).inflate(R.layout.subscription_row_layout,parent,false);
return new ViewHolder(v);
}
//A ViewHolder object stores each of the component views inside the tag field of the Layout, so you can immediately access them without the need to look them up repeatedly.
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Subscription subscription = mDataSet.get(position);
holder.nameTV.setText(subscription.getName());
holder.numberTV.setText(subscription.getNumber());
holder.priceTV.setText(String.format(mContext.getResources().getString(R.string.subscriptionAdapterPrice), subscription.getPrice()));
}
#Override
public int getItemCount(){
return mDataSet.size();
}
}
When Firebase loads data in the order first node -> last node. Since in your structure, the order was enterprise ->...-> small, so it loads the data that way. So given if you already 5 five fixed node, you may want to reorder your structure as small -> micro -> medium -> large -> enterprise.
You can also use several Sort Data Method that firebase provided.
In your case, since you only have 5 nodes, you probably can just do a Collections.sort(arraylist, Collections.reverseOrder()) if you're reading them into an ArrayList
It is simple
Since you are using firebase datastore.
You can sort the values by these 3 methods in it.
orderByChild()
orderByKey()
orderByValue()
My app contains a series of long texts, and I'd like the user to be able to return to them at the point where they left off if they leave that View.
I've adapted the code from this answer for a ListView. The first Log is fine, but the second does not, which suggests to me that state is null.
Here's my StoryBodyActivity:
public class StoryBodyActivity extends AppCompatActivity {
private TextView storyBodyTextView;
private ScrollView storyBodyScrollView;
Parcelable state;
#Override
public void onPause() {
Log.d("pause", "saving listview state # onPause");
state = storyBodyTextView.onSaveInstanceState();
super.onPause();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_story_body);
Bundle extras = getIntent().getExtras();
String story = extras.getString("story");
setTitle(story);
storyBodyTextView = (TextView) findViewById(R.id.story_body_text_view);
storyBodyScrollView = (ScrollView) findViewById(R.id.story_body_scroll_view);
DatabaseHelper db = new DatabaseHelper(this);
String storyBody = db.getStoryBody(story);
storyBodyTextView.setText(Html.fromHtml(storyBody));
if(state != null) {
Log.d("pause", "trying to restore textview state..");
storyBodyTextView.onRestoreInstanceState(state);
}
}
}
I also need to ensure that the position of each individual long text is saved.
Here's the DatabaseHelper to show where the data is coming from:
public String getStoryBody(String story) {
Log.i("test", "hello");
String storyBody = "";
// Select all query
String selectQuery = "SELECT * FROM " + BOOKS + " WHERE title = '" + story + "'";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
storyBody = cursor.getString(4);
} while (cursor.moveToNext());
}
return storyBody;
}
I have a second activity that handles all the user input and another activity that handles all the data from the second activity. What I want to do is call a class "SubmitName" from the activity to the second activity so that I dont need to pass the values from second activity to the main activity anymore. Here are the codes..
MainActivity (Where the class "SubmitName" are located and values are passed.)
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
TextView Name;
String lastname;
String licensenumber;
String mviolation;
String maplace;
String maddress;
String phonenumber;
String officername;
String contactnumber;
String datetime;
RecyclerView.LayoutManager layoutManager;
RecyclerAdapter adapter;
ArrayList<Violator> arrayList = new ArrayList<>();
BroadcastReceiver broadcastReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button addBtn = (Button)findViewById(R.id.btnAdd);
addBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, FragActivity.class);
startActivity(intent);
}
});
recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
Name = (TextView) findViewById(R.id.tvName);
Intent intent = getIntent();
String str = intent.getStringExtra("firstname");
lastname = intent.getStringExtra("lastname");
licensenumber = intent.getStringExtra("licensenumber");
mviolation = intent.getStringExtra("violation");
maplace = intent.getStringExtra("arrestplace");
maddress = intent.getStringExtra("address");
phonenumber = intent.getStringExtra("phonenumber");
contactnumber = intent.getStringExtra("contactnumber");
officername = intent.getStringExtra("officername");
datetime = intent.getStringExtra("datetime");
Name.setText(str);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
adapter = new RecyclerAdapter(arrayList);
recyclerView.setAdapter(adapter);
readFromLocalStorage();
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
readFromLocalStorage();
}
};
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.nav_bar, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.TrafficAd:
Intent i = new Intent(this, TrafficAdvisory.class);
this.startActivity(i);
break;
}
return super.onOptionsItemSelected(item);
}
public void submitName(View view)
{
String name = Name.getText().toString();
String lname = lastname;
String lnumber = licensenumber;
String violation = mviolation;
String aplace = maplace;
String address = maddress;
String pnumber = phonenumber;
String cnumber = contactnumber;
String oname = officername;
String dtime = datetime;
saveToAppServer(name,lname,lnumber,violation,aplace,address,pnumber,cnumber,oname,dtime);
Name.setText("");
}
public void readFromLocalStorage()
{
arrayList.clear();
DbHelper dbHelper = new DbHelper(this);
SQLiteDatabase database = dbHelper.getReadableDatabase();
Cursor cursor = dbHelper.readFromLocalDatabase(database);
while (cursor.moveToNext())
{
String name = cursor.getString(cursor.getColumnIndex(DBContract.NAME));
String lname = cursor.getString(cursor.getColumnIndex(DBContract.LNAME));
String lnumber = cursor.getString(cursor.getColumnIndex(DBContract.LNUMBER));
String violation = cursor.getString(cursor.getColumnIndex(DBContract.VIOLATION));
String aplace = cursor.getString(cursor.getColumnIndex(DBContract.ARRESTPLACE));
String address = cursor.getString(cursor.getColumnIndex(DBContract.ADDRESS));
String pnumber = cursor.getString(cursor.getColumnIndex(DBContract.PNUMBER));
String cnumber = cursor.getString(cursor.getColumnIndex(DBContract.CNUMBER));
String oname = cursor.getString(cursor.getColumnIndex(DBContract.ONAME));
String dtime = cursor.getString(cursor.getColumnIndex(DBContract.DTIME));
int sync_status = cursor.getInt(cursor.getColumnIndex(DBContract.SYNC_STATUS));
arrayList.add(new Violator(name,lname,lnumber,violation,aplace,address,pnumber,cnumber,oname,dtime,sync_status));
}
adapter.notifyDataSetChanged();
cursor.close();
}
public void saveToAppServer(final String name,final String lname, final String lnumber,final String violation, final String aplace,final String address, final String pnumber, final String cnumber, final String oname, final String dtime)
{
if (checkNetworkConnection())
{
StringRequest stringRequest = new StringRequest(Request.Method.POST,DBContract.SERVER_URL,
new Response.Listener<String>(){
#Override
public void onResponse(String response){
try {
JSONObject jsonObject = new JSONObject(response);
String Response = jsonObject.getString("response");
if(Response.equals("OK"))
{
saveToLocalStorage(name,lname,lnumber,violation,aplace,address,pnumber,cnumber,oname,dtime,DBContract.SYNC_STATUS_OK);
}
else
{
saveToLocalStorage(name,lname,lnumber,violation,aplace,address,pnumber,cnumber,oname,dtime,DBContract.SYNC_STATUS_FAILED);
}
} catch (JSONException e){
e.printStackTrace();
}
}
},new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error){
saveToLocalStorage(name,lname,lnumber,violation,aplace,address,pnumber,cnumber,oname,dtime,DBContract.SYNC_STATUS_FAILED);
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("name",name);
params.put("lname",lname);
params.put("lnumber",lnumber);
params.put("violation", violation);
params.put("aplace", aplace);
params.put("address",address);
params.put("pnumber",pnumber);
params.put("cnumber",cnumber);
params.put("oname",oname);
params.put("dtime",dtime);
return params;
}
}
;
MySingleton.getInstance(MainActivity.this).addToRequestQue(stringRequest);
}
else
{
saveToLocalStorage(name,lname,lnumber,violation,aplace,address,pnumber,cnumber,oname,dtime,DBContract.SYNC_STATUS_FAILED);
}
}
SecondActivity (Where inputs are handled and data passing to the mainactivity)
public class ViolatorDetail extends AppCompatActivity implements View.OnClickListener{
EditText Name;
Button btnClose;
TextView DTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_violator_detail);
DTime = (TextView)findViewById(R.id.tvDTime);
final String currentDT = DateFormat.getDateTimeInstance().format(new Date());
DTime.setText(currentDT);
btnClose = (Button) findViewById(R.id.btnClose);
btnClose.setOnClickListener(this);
Button btnSubmit = (Button)findViewById(R.id.btnSubmit);
btnSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
EditText Name = (EditText)findViewById(R.id.etfName);
EditText LName = (EditText)findViewById(R.id.etlName);
EditText LNumber = (EditText)findViewById(R.id.etlNumber);
EditText Violation = (EditText)findViewById(R.id.etViolation);
EditText Arrestplace = (EditText)findViewById(R.id.etaPlace);
EditText Address = (EditText)findViewById(R.id.etAddress);
EditText PNumber = (EditText)findViewById(R.id.etpNumber);
EditText CNumber = (EditText)findViewById(R.id.etcNumber);
EditText OName = (EditText)findViewById(R.id.etoName);
String DT = DTime.getText().toString();
Intent intent = new Intent(ViolatorDetail.this, MainActivity.class);
intent.putExtra("firstname", Name.getText().toString());
intent.putExtra("lastname", LName.getText().toString());
intent.putExtra("licensenumber", LNumber.getText().toString());
intent.putExtra("violation", Violation.getText().toString());
intent.putExtra("arrestplace", Arrestplace.getText().toString());
intent.putExtra("address", Address.getText().toString());
intent.putExtra("phonenumber", PNumber.getText().toString());
intent.putExtra("contactnumber", CNumber.getText().toString());
intent.putExtra("officername", OName.getText().toString());
intent.putExtra("datetime", DT);
startActivity(intent);
}
});
}
}
What I want to do is call the "SUBMITNAME" class to the second activity so that no data passing will be done anymore.
As other friends mentioned Intent is a correct and good way to transfer data between activities. But if you want to avoid writing so much code to transfer data I suggest to create a pure java class (or java bean) and define all needed fields in that class (note: this class should implement java.io.Serializable interface). Now you could transfer instances of this class between activities.
I don’t think there is a better way of passing data between activities than Intents.
What you probably need is encapsulation of passing of extra. You can achieve this by making a static method in the ViolatorDetail class, which accepts as arguments as values you would like to pass, and returns Intent.
public static Intent newIntent(Context packageContext, String ... args){
Intent intent = new Intent(packageContext, ViolatorDetail.this);
intent.putExtra(EXTRA_STRING_ARGS, args);
return intent;
}
Then in the caller class you make an intent by makeing a static call on that function, and pass values as arguments
Intent intent = ViolatorDetail.newIntent(getActivity(), strings)
startActivity(intent);
However, in your case, you should probably make a more sensible way of passing data than as array of strings.
If you don't want to pass data between Activities with Intent, you can do it by writing certain data in a file and when you need it just read from it... I did it like this and I'm still happy i did it that way, it's simple and relatively quick, you just have to care a little about IOExceptions.