Here is my situation.
In this screen, I click the comments button.
The Comment activity opens and I type what I want.
The comment is added successfully in firebase and it takes me back in detail activity.
So far everything is great! Now let's add another comment. Now you see I get duplicate comments.
I hope you see that too. Now in the DetailActivity I have a method called queryFirebaseDb() and that method is called inside both onCreate() and onResume() methods. If I don't use the onResume() method the data will not be display after clicking the back button from the CommentActivity. You see where I am going now right? The question is how to avoid duplicate data after coming back from CommentActivity. Here is my code.
public class DetailActivity extends AppCompatActivity {
ArrayList<Comment> commentArrayList;
ImageView mImageView;
TextView mTitle;
TextView mDate;
TextView mDescription;
TextView mAuthor;
ToggleButton mFavBtn;
private TextView noCommentsTextView;
private TextView commentsTextView;
private ImageButton imageButton;
private FloatingActionButton mShareBtn;
private String newsTitle;
private String newsImage;
private String newsDate;
private String newsDescription;
private static String NEWS_SHARE_HASHTAG = "#EasyNewsApp";
private String date1;
private String date2;
private String newsUrl;
private String newsAuthor;
private Cursor favoriteCursor;
private DatabaseReference mDatabase;
private static Bundle bundle = new Bundle();
private Uri uri;
private RecyclerView mRecyclerView;
private DisplayCommentsAdapter displayCommentsAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Toolbar toolbar = (Toolbar) findViewById(R.id.detail_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Intent i = getIntent();
mAuthor = (TextView) findViewById(R.id.detail_author);
mImageView = (ImageView) findViewById(R.id.detail_image_view);
mTitle = (TextView) findViewById(R.id.detail_title);
mDate = (TextView) findViewById(R.id.detail_publish_date);
mDescription = (TextView) findViewById(R.id.detail_description);
noCommentsTextView = (TextView)findViewById(R.id.noCommentsTextView);
commentsTextView = (TextView)findViewById(R.id.commentsTextView);
mShareBtn = (FloatingActionButton) findViewById(R.id.share_floating_btn);
mFavBtn = (ToggleButton) findViewById(R.id.fav_news_btn);
imageButton = (ImageButton)findViewById(R.id.detail_comment_image_btn);
mRecyclerView = (RecyclerView)findViewById(R.id.recycler_comments);
LinearLayoutManager manager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(manager);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));
commentArrayList = new ArrayList<>();
mDatabase = FirebaseDatabase.getInstance().getReference();
mFavBtn.setTextOn(null);
mFavBtn.setText(null);
mFavBtn.setTextOff(null);
newsAuthor = i.getStringExtra("author");
newsImage = i.getStringExtra("image");
newsTitle = i.getStringExtra("newsTitle");
newsDate = i.getStringExtra("date");
newsDescription = i.getStringExtra("description");
newsUrl = i.getStringExtra("url");
date1 = newsDate.substring(0, 10);
date2 = newsDate.substring(11, 19);
Picasso.with(this).load(newsImage)
.placeholder(R.drawable.ic_broken_image)
.into(mImageView);
mTitle.setText(newsTitle);
mAuthor.setText("Author: " + newsAuthor);
mDescription.setText(newsDescription);
mDate.setText(date2 + ", " + date1);
mShareBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent shareIntent = createShareNewsIntent();
startActivity(shareIntent);
}
});
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent commentIntent = new Intent(DetailActivity.this, CommentActivity.class);
commentIntent.putExtra("newsTitle",newsTitle);
startActivity(commentIntent);
}
});
/**
* Handling the add/remove news part. We check if the specific news article
* exists in favourite.db.
*/
favoriteCursor = getContentResolver().query(FavouriteContract.FavouriteEntry.CONTENT_URI,
null,
FavouriteContract.FavouriteEntry.COLUMN_NEWS_TITLE + "=?",
new String[]{newsTitle},
null);
/**
* If yes then set the toggle button to true
*/
if (favoriteCursor.getCount() > 0) {
try {
mFavBtn.setChecked(true);
} finally {
favoriteCursor.close();
}
}
/**
* Else click the toggle button to add the news article as favourite
*/
mFavBtn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, final boolean isChecked) {
/**
* If checked the add the news article as favourite.
*/
if (isChecked) {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
ContentValues contentValues = new ContentValues();
contentValues.put(FavouriteContract.FavouriteEntry.COLUMN_NEWS_TITLE, newsTitle);
contentValues.put(FavouriteContract.FavouriteEntry.COLUMN_NEWS_AUTHOR, newsAuthor);
contentValues.put(FavouriteContract.FavouriteEntry.COLUMN_NEWS_DESCRIPTION, newsDescription);
contentValues.put(FavouriteContract.FavouriteEntry.COLUMN_NEWS_URL, newsUrl);
contentValues.put(FavouriteContract.FavouriteEntry.COLUMN_NEWS_URL_TO_IMAGE, newsImage);
contentValues.put(FavouriteContract.FavouriteEntry.COLUMN_NEWS_PUBLISHED_AT, newsDate);
//The actual insertion in the db.
uri = getContentResolver().insert(FavouriteContract.FavouriteEntry.CONTENT_URI, contentValues);
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Toast.makeText(DetailActivity.this, "Article with title: " + newsTitle + " was added", Toast.LENGTH_SHORT).show();
}
}.execute();
} else {
/**
* If you uncheck the toggle button then delete the news article from the favourite db.
*/
Uri newsTitleOfFavNews = FavouriteContract.FavouriteEntry.buildNewsUriWithTitle(newsTitle);
//String title = uri.getPathSegments().get(1);// Get the task ID from the URI path
getContentResolver().delete(
newsTitleOfFavNews,
null,
null);
Toast.makeText(DetailActivity.this, "News article deleted from favourites ", Toast.LENGTH_SHORT).show();
}
}
});
queryFirebaseDb();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.detail_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
if(item.getItemId() == R.id.detail_browser_btn){
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(newsUrl));
startActivity(browserIntent);
} if(item.getItemId() == android.R.id.home){
NavUtils.navigateUpFromSameTask(this);
return true;
}
return true;
}
private Intent createShareNewsIntent() {
Intent shareIntent = ShareCompat.IntentBuilder.from(this)
.setType("text/plain")
.setText(NEWS_SHARE_HASHTAG + "\n\n\n" + newsTitle
+ "\n\n\n" + newsDescription
+ "\n\n\n" + newsDate)
.getIntent();
return shareIntent;
}
#Override
protected void onStart() {
super.onStart();
//queryFirebaseDb();
}
#Override
protected void onRestart() {
super.onRestart();
queryFirebaseDb();
//displayCommentsAdapter.notifyDataSetChanged();
}
public void queryFirebaseDb(){
/**
* Querying the database to check if the specific article has comments.
*/
mDatabase = FirebaseDatabase.getInstance().getReference();
Query query = mDatabase.child("comments").orderByChild("newsTitle").equalTo(newsTitle);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
for(DataSnapshot dataSnapshots : dataSnapshot.getChildren()){
Comment comment = dataSnapshots.getValue(Comment.class);
//mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(userId);
commentArrayList.add(comment);
displayCommentsAdapter = new DisplayCommentsAdapter(this,commentArrayList);
mRecyclerView.setAdapter(displayCommentsAdapter);
displayCommentsAdapter.setCommentsData(commentArrayList);
//Log.d(LOG_TAG, String.valueOf(commentArrayList.size()));
}
noCommentsTextView.setVisibility(View.GONE);
//commentsTextView.setVisibility(View.VISIBLE);
}else{
//Toast.makeText(DisplayComments.this,"There are no comments posted",Toast.LENGTH_LONG).show();
noCommentsTextView.setVisibility(View.VISIBLE);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
/*
#Override
protected void onPause() {
super.onPause();
bundle.putBoolean("ToggleButtonState", mFavBtn.isChecked());
}
#Override
public void onResume() {
super.onResume();
mFavBtn.setChecked(bundle.getBoolean("ToggleButtonState",false));
}
*/
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mFavBtn.setChecked(savedInstanceState.getBoolean("ToggleButtonState",false));
savedInstanceState.putParcelableArrayList("newsList",commentArrayList);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("ToggleButtonState",mFavBtn.isChecked());
outState.getParcelableArrayList("newsList");
}
}
and
public class CommentActivity extends AppCompatActivity {
private static final String REQUIRED = "Required";
private static final String TAG = CommentActivity.class.getSimpleName();
Toolbar toolbar;
DatabaseReference mDatabase;
EditText titleEt;
EditText bodyEt;
Button commentBtn;
String newsTitle;
Intent i;
String name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_comment);
toolbar = (Toolbar) findViewById(R.id.comment_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Add comment");
mDatabase = FirebaseDatabase.getInstance().getReference();
titleEt = (EditText) findViewById(R.id.comment_title);
bodyEt = (EditText) findViewById(R.id.comment_body);
commentBtn = (Button) findViewById(R.id.comment_btn);
i = getIntent();
newsTitle = i.getStringExtra("newsTitle");
commentBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
submitPost();
}
});
}
private void submitPost() {
final String title = titleEt.getText().toString();
final String body = bodyEt.getText().toString();
// Title is required
if (TextUtils.isEmpty(title)) {
titleEt.setError(REQUIRED);
return;
}
// Body is required
if (TextUtils.isEmpty(body)) {
bodyEt.setError(REQUIRED);
return;
}
// Disable button so there are no multi-posts
setEditingEnabled(false);
Toast.makeText(this, "Posting...", Toast.LENGTH_SHORT).show();
// [START single_value_read]
final String userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
mDatabase.child("Users").child(userId).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get user value
User user = dataSnapshot.getValue(User.class);
// [START_EXCLUDE]
if (user == null) {
// User is null, error out
Log.e(TAG, "User " + userId + " is unexpectedly null");
Toast.makeText(CommentActivity.this,
"Error: could not fetch user.",
Toast.LENGTH_SHORT).show();
} else {
// Write new post
name = dataSnapshot.child("name").getValue().toString();
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
String strDate = sdf.format(c.getTime());
writeNewPost(userId,strDate,name,newsTitle, title, body);
}
// Finish this Activity, back to the stream
setEditingEnabled(true);
finish();
// [END_EXCLUDE]
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "getUser:onCancelled", databaseError.toException());
// [START_EXCLUDE]
setEditingEnabled(true);
// [END_EXCLUDE]
}
});
// [END single_value_read]
}
private void writeNewPost(String userId,String date,String
commentAuthor, String newsTitle, String commentTitle, String
commentBody){
String key = mDatabase.child("comments").push().getKey();
Comment comment = new Comment(userId, date,
commentAuthor,newsTitle,commentTitle,commentBody);
Map<String, Object> commentValues = comment.toMap();
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/comments/" + key, commentValues);
mDatabase.updateChildren(childUpdates);
}
private void setEditingEnabled(boolean enabled) {
titleEt.setEnabled(enabled);
bodyEt.setEnabled(enabled);
if (enabled) {
commentBtn.setVisibility(View.VISIBLE);
} else {
commentBtn.setVisibility(View.GONE);
}
}
}
UPDATE
I used this
#Override
protected void onRestart() {
super.onRestart();
finish();
startActivity(getIntent());
}
and voila!
Some stuff I thought you would know when doing Android:
Basically, in android, you need to understand how the life cycle works. So, when you call queryFirebaseDb() from onCreate and from onResume, your app is doing two queries at the same time when activity starts initially.
Lifecycle is like this OnCreate -> onResume. So, it makes sense that when activity starts, query gets executed once on onCreate than on onResume based on your logic.
Answer is here
I noticed that you are using ArrayList<Comment> commentArrayList;, which is an ArrayList structure, which lets you have duplicate data. And, if you look into the behavior of Firebase and how your query is structured, it is like this,
Query query = mDatabase.child("comments").orderByChild("newsTitle").equalTo(newsTitle);
This query means that you are taking all the comments, the previous comment and the new comment, (not just new comment), which I think you either just want (1) to get recently added comment or (2) to replace the old comments with new one.
The first way of doing this sounds complicated to me, though that is not impossible. But, second way of doing is rather easy.
Therefore, to solve this,
simply, replace the arrayList you have with this data.
if(dataSnapshot.exists()){
ArrayList<Comment> tempComments = new ArrayList();
for(DataSnapshot dataSnapshots : dataSnapshot.getChildren()){
Comment comment = dataSnapshots.getValue(Comment.class);
//mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(userId);
tempComments.add(comment);
//Log.d(LOG_TAG, String.valueOf(commentArrayList.size()));
}
commentArrayList = tempComments; //assuming you want to store the data in the class fields
displayCommentsAdapter = new DisplayCommentsAdapter(this,commentArrayList);
mRecyclerView.setAdapter(displayCommentsAdapter);
displayCommentsAdapter.setCommentsData(commentArrayList);
noCommentsTextView.setVisibility(View.GONE);
//commentsTextView.setVisibility(View.VISIBLE);
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am new to android i have made a project to store members information in one activity and in another activity i display members in listView and on onlong clicking listview i open another activity to update members information but when i click on update button it adds that record instead of Updating.
My Firebase Structure :
My activity for storing :
public class MainActivity extends AppCompatActivity {
EditText txtname,txtage,txtheight,txtphone;
Button btnsave,btnRead;
Member member;
DatabaseReference reff;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtname = findViewById(R.id.txtname);
txtage =findViewById(R.id.txtage);
txtphone =findViewById(R.id.txtphone);
txtheight =findViewById(R.id.txtheight);
btnsave = (Button)findViewById(R.id.btnsave);
btnRead =(Button)findViewById(R.id.btnRead);
btnRead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openActivity();
}
private void openActivity() {
Intent intent = new Intent(MainActivity.this, Retreivedata.class);
startActivity(intent);
}
});
member = new Member();
reff = FirebaseDatabase.getInstance().getReference().child("Member");
btnsave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AddUsers();
}
});
}
private void AddUsers(){
String name = txtname.getText().toString().trim();
String age = txtage.getText().toString().trim();
String phone = txtphone.getText().toString().trim();
String ht = txtheight.getText().toString().trim();
if(!TextUtils.isEmpty(name)) {
String id = reff.push().getKey();
Member member = new Member(id, name, age, phone, ht);
reff.child(id).setValue(member);
Toast.makeText(this,"User Inserted Successfully",Toast.LENGTH_LONG).show();
txtheight.setText("");
txtphone.setText("");
txtage.setText("");
txtname.setText("");
}else {
txtname.setError("Enter Name");
}
}
}
My activity for displaying records in listview:
public class Retreivedata extends AppCompatActivity {
ListView listView;
FirebaseDatabase database;
DatabaseReference ref;
ArrayList<Member> list;
ArrayAdapter<Member> adapter;
Member member;
Button btnDlt;
Boolean a=false;
String val="";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_retreivedata);
member = new Member();
listView =(ListView)findViewById(R.id.listView);
btnDlt = (Button) findViewById(R.id.btnDlt);
database = FirebaseDatabase.getInstance();
ref = database.getReference("Member");
list = new ArrayList<>();
adapter = new ArrayAdapter<Member>(this,R.layout.list_white_text,R.id.userInfo, list);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dts: dataSnapshot.getChildren())
{
member = dts.getValue(Member.class);
list.add(member);
}
listView.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
btnDlt.setEnabled(false);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Boolean a=true;
Member member=adapter.getItem(position);
Toast.makeText(Retreivedata.this,"Do u want to delete this record!!",Toast.LENGTH_LONG).show();
if (a==true)
{
btnDlt.setEnabled(true);
}else{
btnDlt.setEnabled(false);
}
}
});
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Member member= adapter.getItem(position);
Intent intent = new Intent(Retreivedata.this, Update.class);
intent.putExtra("tem", member);
startActivity(intent);
return false;
}
});
btnDlt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ref.child(member.getMemberId()).removeValue();
Toast.makeText(Retreivedata.this, "Record deleted Successfully",
Toast.LENGTH_LONG).show();
adapter.remove(member);
adapter.clear();
}
});
}
}
My activity for updating record:
public class Update extends AppCompatActivity {
EditText EditTxtName,EditTxtAge,txtPhone,txtHeight;
Member member;
FirebaseDatabase db;
DatabaseReference reff;
Button btnUpdate;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);
EditTxtName = (EditText)findViewById(R.id.EditTxtName);
EditTxtAge = (EditText)findViewById(R.id.EditTxtAge);
txtPhone = (EditText)findViewById(R.id.txtPhone);
txtHeight = (EditText)findViewById(R.id.txtHeight);
btnUpdate = (Button)findViewById(R.id.btnUpdate);
final Member member= (Member) getIntent().getSerializableExtra("tem");
EditTxtName.setText(member.getName());
EditTxtAge.setText(member.getAge());
txtPhone.setText(member.getPhone());
txtHeight.setText(member.getHeight());
reff = db.getInstance().getReference().child("Member");
btnUpdate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Update();
}
});
}
private void Update(){
final String mnam = EditTxtName.getText().toString().trim();
final String mage = EditTxtAge.getText().toString().trim();
final String mph = txtPhone.getText().toString().trim();
final String mhei = txtHeight.getText().toString().trim();
final String ID = reff.getKey();
if(TextUtils.isEmpty(mnam)) {
EditTxtName.setText("Plz enter name");}
if(TextUtils.isEmpty(mage)) {
EditTxtName.setText("Plz enter age");}
else{
final Member member = new Member(ID,mnam,mage,mph,mhei);
reff.child("Member").child(ID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
reff = FirebaseDatabase.getInstance().getReference();
reff.child("Member").child(ID).child("name").setValue(mnam);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Toast.makeText(Update.this,"Updated",Toast.LENGTH_LONG).show();
txtHeight.setText("");
txtPhone.setText("");
EditTxtName.setText("");
}
}
}
But after updating record it creates another record.Suggest me what changes has to be done on update button click.
Thnaks!!
First I assume that you implement Serializable for your Member class:
class Member implements Serializable{
.............
.............
.............
}
Since you are passing the member object to the update activity, why not use the ID in it to update the data:
//the update activity
public class Update extends AppCompatActivity {
//this is the member that you pass
Member member;
......
......
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
.........
.........
//this is how you retrieve it
member= (Member) getIntent().getSerializableExtra("tem");
//this is your ref
reff = db.getInstance().getReference().child("Member");
........
........
}
//when you update
private void Update(){
final String mnam = EditTxtName.getText().toString().trim();
final String mage = EditTxtAge.getText().toString().trim();
final String mph = txtPhone.getText().toString().trim();
final String mhei = txtHeight.getText().toString().trim();
//update the name field
reff.child(member.getMemberId()).child("name").setValue(mnam);
}
Your problem is this line of code final String ID = reff.getKey()
That call generates a new ID which you then use in your update of the db. You need to replace the call to getKey with the ID of the member you want to update.
I have a problem with my RecyclerView.
I have a ProductDetailActivity which shows the detail of a product and i have a RecyclerView with its adapter in it.
The user can click on the give rating button which navigates to the RatingActivity where you can give a rating to the product.
The problem is that when i submit my rating and automatically go back to my RatingActivity, the RecyclerView does not get the recently added rating. i have to go back to my productlist and reclick on the product to see the recently added rating.
Here is my code:
ProductDetailActivity:
public class ProductDetailActivity extends AppCompatActivity {
public AppDatabase appDatabase;
private static final String DATABASE_NAME = "Database_Shop";
private RecyclerView mRecycleviewRating;
private RatingAdapter mAdapterRating;
private Button btnGoToRatingActivity;
List<Rating> ratings;
Product p;
int id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_detail);
appDatabase = Room.databaseBuilder(getApplicationContext(),AppDatabase.class,DATABASE_NAME)
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build();
btnGoToRatingActivity = findViewById(R.id.btn_goToRatingActivity);
Intent intent = getIntent();
id = intent.getIntExtra("productid", -1);
// pour montrer tous les ratings d'un produit, tu fais un getall
p = appDatabase.productDAO().getProductById(id);
ImageView imageView = findViewById(R.id.imageDetail);
TextView textViewName = findViewById(R.id.txt_nameDetail);
TextView textViewAuthor = findViewById(R.id.txt_authorDetail);
TextView textViewCategory = findViewById(R.id.txt_categoryDetail);
TextView textViewDetail = findViewById(R.id.txt_descriptionDetail);
Picasso.get().load(p.getProductImage()).fit().centerInside().into(imageView);
textViewName.setText(p.getProductName());
textViewAuthor.setText(p.getProductAuthor());
textViewCategory.setText(p.getProductCategory());
textViewDetail.setText(p.getProductDescription());
ratings = appDatabase.ratingDAO().getRatingByProductId(id);
mRecycleviewRating = findViewById(R.id.recyclerRating_view);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecycleviewRating.setLayoutManager(linearLayoutManager);
//recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapterRating = new RatingAdapter(ratings);
mRecycleviewRating.setAdapter(mAdapterRating);
btnGoToRatingActivity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(ProductDetailActivity.this, RatingActivity.class);
i.putExtra("productid", p.getProduct_id());
startActivity(i);
}
});
mAdapterRating.notifyDataSetChanged();
}
#Override
public void onResume() {
super.onResume();
ratings = appDatabase.ratingDAO().getRatingByProductId(id); // reload the items from database
mAdapterRating.notifyDataSetChanged();
System.out.println(mAdapterRating.ratings.size());
}
}
RatingActivity:
public class RatingActivity extends AppCompatActivity implements RatingGiveFragment.RatingListener {
RelativeLayout mRelativeLayout;
private Button btnConfirmRating;
private EditText mComment;
private RatingBar mRatingBar;
public AppDatabase appDatabase;
private RatingAdapter mAdapter;
List<Rating> ratings;
private static final String DATABASE_NAME = "Database_Shop";
Product p;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rating);
appDatabase = Room.databaseBuilder(getApplicationContext(),AppDatabase.class,DATABASE_NAME)
.allowMainThreadQueries()
.fallbackToDestructiveMigration()
.build();
int idProduct = RatingActivity.this.getIntent().getIntExtra("productid",-1);
p = appDatabase.productDAO().getProductById(idProduct);
mRatingBar = findViewById(R.id.rating_bar);
mComment = findViewById(R.id.txt_insertOpinionText);
mRelativeLayout = findViewById(R.id.activity_rating);
btnConfirmRating = findViewById(R.id.buttonConfirmRating);
mAdapter = new RatingAdapter(ratings);
btnConfirmRating.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!checkEmptyFields()) {
Rating rating = new Rating(p.getProduct_id(),UserConnected.connectedUser.getUser_id(),mRatingBar.getRating(), UserConnected.connectedUser.getUsername(), mComment.getText().toString());
appDatabase.ratingDAO().insertRating(rating);
mAdapter.notifyDataSetChanged();
finish();
}else{
Toast.makeText(RatingActivity.this, "Empty Fields", Toast.LENGTH_SHORT).show();
}
}
});
}
/*private class insertRating extends AsyncTask<String,Integer, Integer>
{
#Override
protected Integer doInBackground(String... strings) {
Rating rating = new Rating(Integer.parseInt(strings[0]), Integer.parseInt(strings[1]), Integer.parseInt(strings[2]), strings[3], strings[4]);
appDatabase.ratingDAO().insertRating(rating);
return 1;
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
if (integer == 1)
{
Toast.makeText(getApplicationContext(), getString(R.string.createRating), Toast.LENGTH_SHORT).show();
}
}
}*/
#Override
public void ratingChanged(int newRating) {
RatingTextFragment textFragment = (RatingTextFragment) getSupportFragmentManager().findFragmentById(R.id.fmt_text);
textFragment.setRating(newRating);
}
private boolean checkEmptyFields(){
if(TextUtils.isEmpty(mComment.getText().toString())){
return true;
}else{
return false;
}
}
}
RatingAdapter:
public class RatingAdapter extends RecyclerView.Adapter<RatingAdapter.RatingViewHolder> {
List<Rating> ratings;
public RatingAdapter(List<Rating> ratings){
this.ratings = ratings;
}
#NonNull
#Override
public RatingViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.rating_row,viewGroup, false);
return new RatingViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull RatingViewHolder ratingViewHolder, int position) {
ratingViewHolder.ratingUsername.setText(ratings.get(position).getRatingUsername());
ratingViewHolder.ratingNumber.setText(String.valueOf(ratings.get(position).getRatingNumber()) + "/5");
ratingViewHolder.ratingComment.setText(ratings.get(position).getRatingText());
}
#Override
public int getItemCount() {
return ratings.size();
}
public static class RatingViewHolder extends RecyclerView.ViewHolder{
public TextView ratingUsername;
public TextView ratingNumber;
public TextView ratingComment;
public RatingViewHolder(#NonNull View itemView) {
super(itemView);
ratingUsername = itemView.findViewById(R.id.txt_usernamerating);
ratingNumber = itemView.findViewById(R.id.num_rating);
ratingComment = itemView.findViewById(R.id.txt_ratingComment);
}
}
}
Pictures:
You get no update in the ProductDetailActivity because you are not updating the data object ratings in the ProductDetailActivity that is the basis for the RatingAdapter.
It would be better to use startActivityForResult in the onClick()method of the ProductDetailActivity. Then you need to override the onActivityResult() method in the ProductDetailActivity. Evaluate the return values and update your data source if necessary, then call notifyDataSetChanged.
This is just pseudo code!
Changes to ProductDetailActivity:
btnGoToRatingActivity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(ProductDetailActivity.this, RatingActivity.class);
i.putExtra("productid", p.getProduct_id());
// with this you are telling the activity to expect results and..
//..to deal with them in onActivityResult
startActivityForResult(i, 1);
}
});
// You do not need this next line because setting the adaper triggers the first
//mAdapterRating.notifyDataSetChanged();
}
Add the onActivityResult() method to the ProductDetailActivity.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == Activity.RESULT_OK){
// trigger a method to update the data object that is linked to the adapter
ratings = appDatabase.ratingDAO().getRatingByProductId(id);
// and now that the data has actually been updated you can call notifyDataSetChanged!!
mAdapterRating.notifyDataSetChanged();
}
if (resultCode == Activity.RESULT_CANCELED) {
//Probably do nothing or make a Toast "Canceled"??
}
}
}
Changes to RatingActivity:
btnConfirmRating.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!checkEmptyFields()) {
// I will just assume this works!
Rating rating = new Rating(p.getProduct_id(),UserConnected.connectedUser.getUser_id(),mRatingBar.getRating(), UserConnected.connectedUser.getUsername(), mComment.getText().toString());
appDatabase.ratingDAO().insertRating(rating);
Intent intent = new Intent();
//If you need to return some value.. do it here other you do not need it
//intent.putExtra("result", result);
setResult(Activity.RESULT_OK, intent);
finish();
}else{
Toast.makeText(RatingActivity.this, "Empty Fields", Toast.LENGTH_SHORT).show();
}
}
});
Please be aware in RatingActivity that in btnConfirmRating.setOnClickListener notifying the adapter with mAdapter.notifyDataSetChanged(); does nothing: firstly, because the adapter in the RatingActivity has nothing to do with the adapter in the ProductDetailActivity; secondly: you call finish(); in the next line of code.
I have this code. It displays two recycler views and wants to store their scroll positions for the rotation purpose. So here is my code.
public class DetailActivity extends AppCompatActivity implements DetailViewInteface, TrailersAdapter.TrailersAdapterOnClickHandler {
public static final String IMAGE_URL = "http://image.tmdb.org/t/p/";
public static final String IMAGE_SIZE_185 = "w185";
private static final String TAG = "DetailActivity";
private static final String TRAILERS_LAYOUT = "DetailsActivity.trailer.layout";
private static final String REVIEWS_LAYOUT = "DetailsActivity.review.layout";
private Parcelable listState1;
private Parcelable listState2;
#BindView(R.id.movie_image)
ImageView movieImageTv;
String mImage;
#BindView(R.id.movie_title)
TextView movieTitleTv;
String mTitle;
#BindView(R.id.movie_rating)
TextView movieRatingTv;
double mRating;
#BindView(R.id.movie_date)
TextView movieDateTv;
String mReleaseDate;
#BindView(R.id.movie_overview)
TextView movieOverviewTv;
String mMovieOverview;
#BindView(R.id.recyclerview_trailers)
RecyclerView trailersRecyclerView;
TrailersAdapter trailersAdapter;
#BindView(R.id.recyclerview_reviews)
RecyclerView reviewsRecyclerView;
ReviewAdapter reviewAdapter;
int recyclerViewOrientation = LinearLayoutManager.VERTICAL;
private Parcelable mLayoutManagerSavedState;
DetailPresenter detailPresenter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
ButterKnife.bind(this);
setMVP();
setUpViews();
detailPresenter.getMovieDetails();
detailPresenter.getMovieTrailers();
detailPresenter.getMovieReviews();
}
public void setMVP(){
detailPresenter = new DetailPresenter(this,this);
}
public void setUpViews(){
trailersRecyclerView.setLayoutManager(new LinearLayoutManager(this));
trailersRecyclerView.addItemDecoration(new MyDividerItemDecoration(this,recyclerViewOrientation,16));
reviewsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
reviewsRecyclerView.addItemDecoration(new MyDividerItemDecoration(this,recyclerViewOrientation,16));
}
#Override
public void dipsplayMovieDetails(Movie movie) {
//movieTitleTv.setText(movieTitle);
//movieDescriptionTv.setText(movieDesc);
mImage = movie.getPosterPath();
Picasso.with(this).load(IMAGE_URL + IMAGE_SIZE_185 + mImage).into(movieImageTv);
mTitle = movie.getTitle();
movieTitleTv.setText(mTitle);
mRating = movie.getVoteAverage();
movieRatingTv.setText("Rating: " + mRating);
mReleaseDate = movie.getReleaseDate();
movieDateTv.setText("Date: " + mReleaseDate);
mMovieOverview = movie.getOverview();
movieOverviewTv.setText(mMovieOverview);
}
#Override
public void dipsplayMovieTrailers(TrailersResponse trailersResponse) {
Log.d(TAG, "Trailers size: " + String.valueOf(trailersResponse.getTrailers().size()));
trailersAdapter = new TrailersAdapter(trailersResponse.getTrailers(),DetailActivity.this,this);
trailersRecyclerView.setAdapter(trailersAdapter);
}
#Override
public void displayMovieReviews(ReviewsResponse reviewsResponse) {
if(reviewsResponse != null) {
Log.d(TAG, String.valueOf("Reviews size: " + reviewsResponse.getReviews().size()));
reviewAdapter = new ReviewAdapter(reviewsResponse.getReviews());
reviewsRecyclerView.setAdapter(reviewAdapter);
}else{
Toast.makeText(DetailActivity.this,"No reviews found!",Toast.LENGTH_LONG).show();
}
}
#Override
public void displayError(String s) {
showToast(s);
}
#Override
public void showToast(String s) {
Toast.makeText(DetailActivity.this,s,Toast.LENGTH_LONG).show();
}
#Override
public void onClick(String trailerKey) {
Intent appIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube:" + trailerKey));
Intent webIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.youtube.com/watch?v=" + trailerKey));
try {
startActivity(appIntent);
} catch (ActivityNotFoundException ex) {
startActivity(webIntent);
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(REVIEWS_LAYOUT,reviewsRecyclerView.getLayoutManager().onSaveInstanceState());
outState.putParcelable(TRAILERS_LAYOUT,trailersRecyclerView.getLayoutManager().onSaveInstanceState());
}
}
I use the onSaveInstanceState method. But now I need to restore in the scroll positions of recyclerviews.
I am using the onRestoreInstanceState as below but nothing happens. The rotation gets me to the top of the screen.
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedInstanceState.getParcelable(REVIEWS_LAYOUT);
savedInstanceState.getParcelable(TRAILERS_LAYOUT);
}
So how can I fix that bug?
Thanks,
Theo.
void addOnScrollListener (RecyclerView.OnScrollListener listener)
This is a listener that will be notified of any changes in scroll state or position for a recycler view.
Refer to this answer for an example implementation.
For more on how to use it correctly.
I am working on my first app and am just setting all the frame work up.
That is user sign up via Google, Email, Facebook and saving the data to Firebase.
I started using Realtime Database, which worked fine, but for the proceeding of my project, I think FireStore Cloud would be better suited.
I didnt have much data yet, so it was easy to get it set up.
User signs up or logs in, and if he doesnt exist already, a profile is set up based on the FirebaseAuth Name + Email and some variables I defined ("Nickname", "-"), and a few more.
All good so far. The information is fetched and displayed once the user clicks on his profile.
Then there is the OPTION TO EDIT some data, like the nickname, the age and the nationality.
If I update the data directly on firestore and click on profile again, it displays correctly.
BUT if the user enters the information and clicks the button that triggers the update to the firestore cloud, the app crashes. The database, however, also updates correctly...
I tried a lot things, but Im stuck! Thanks a lot for your help!
MY CODE
USER CLASS => where the information is stored to the cloud one time, when the user logs in
public class User extends AppCompatActivity {
public static final String AGE = "Age";
public static final String EMAIL = "Email";
public static final String FULLNAME = "Full name";
public static final String NATIONALITY = "Nationality";
public static final String NICKNAME = "Nickname";
public static final String STATUS = "Status";
private String userEmail = FirebaseAuth.getInstance().getCurrentUser().getEmail();
private String userFullName = FirebaseAuth.getInstance().getCurrentUser().getDisplayName();
public User() {
// Default constructor required for calls to DataSnapshot.getValue(User.class)
}
protected void checkFireStoreDatabase() {
// Create a new user with a first and last name
FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference usersDocRef = db.collection("Users").document(userFullName);
if (usersDocRef != null) {
} else {
createNewEntry();
}
}
public void createNewEntry() {
FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference usersDocRef = db.collection("Users").document(userFullName);
Map<String, Object> userEntry;
userEntry = new HashMap<>();
userEntry.put("Full name", userFullName);
userEntry.put(EMAIL, userEmail);
userEntry.put("Nickname", "-");
userEntry.put("Age", "-");
userEntry.put("Nationality", "-");
userEntry.put("Status", "Baby monkey");
db.document(userFullName).set(userEntry, SetOptions.merge()).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "Document has been saved");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "Document could not be saved");
}
});
}
USER PROFILE FRAGMENT => where the user can see his information that is stored in the cloud
public class UserProfileFragment extends Fragment implements View.OnClickListener {
private Button btnEditProfile;
//get firestore database data
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private DocumentReference usersDocRef = db.collection("Users").document(FirebaseAuth.getInstance().getCurrentUser().getDisplayName());
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//DATA FROM FIRESTORE
displayFirestoreData();
btnEditProfile = (Button) view.findViewById(R.id.edit_user_info);
btnEditProfile.setOnClickListener(this);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_user_profile, container, false);
}
#Override
public void onClick(View v) {
Fragment fragment = null;
//if the button representing the "train now or create workout" fragment is clicked, create this fragment
if (v.getId() == R.id.edit_user_info) {
fragment = new EditUserProfileFragment();
}
if (fragment != null) {
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.commit();
}
}
public void displayFirestoreData() {
if (usersDocRef != null) {
}
//this.getActivity makes sure the listener only works when in this FragmentActivity
usersDocRef.addSnapshotListener(this.getActivity(), new EventListener<DocumentSnapshot>() {
#Override
public void onEvent(DocumentSnapshot documentSnapshot, FirebaseFirestoreException e) {
if (documentSnapshot.exists()) {
String name = documentSnapshot.getString(FULLNAME);
String email = documentSnapshot.getString(EMAIL);
String nickname = documentSnapshot.getString(NICKNAME);
String age = documentSnapshot.getString(AGE);
String nationality = documentSnapshot.getString(NATIONALITY);
String status = documentSnapshot.getString(STATUS);
//setting all the text views in the user profile
TextView txtProfileName = (TextView) getView().findViewById(R.id.profile_section_fullname);
txtProfileName.setText(name);
TextView txtProfileEmail = (TextView) getView().findViewById(R.id.profile_section_email);
txtProfileEmail.setText(email);
TextView txtProfileNickname = (TextView) getView().findViewById(R.id.profile_section_nickname);
txtProfileNickname.setText(nickname);
TextView txtProfileAge = (TextView) getView().findViewById(R.id.profile_section_age);
txtProfileAge.setText(age);
TextView txtProfileNationality = (TextView) getView().findViewById(R.id.profile_section_nationality);
txtProfileNationality.setText(nationality);
TextView txtProfileStatus = (TextView) getView().findViewById(R.id.profile_section_status);
txtProfileStatus.setText(status);
} else if (e != null) {
Log.w(TAG, "An exception occured", e);
}
}
});
}
EDIT USER PROFILE FRAGMENT => where the user can enter a new nickname, age or nationality
public class EditUserProfileFragment extends Fragment implements View.OnClickListener {
private Button btnSaveProfile;
private EditText editUsername;
private EditText editAge;
private EditText editNationality;
private String username_input;
private String age_input;
private String nationality_input;
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//Button to save the profile
btnSaveProfile = (Button) view.findViewById(R.id.save_user_info);
btnSaveProfile.setOnClickListener(this);
//field that allows changes on the nick name
editUsername = (EditText) view.findViewById(R.id.profile_section_edit_nickname);
//field that allows you to enter the correct age
editAge = (EditText) view.findViewById(R.id.profile_section_edit_age);
//field that allows you to enter your nationality
editNationality = (EditText) view.findViewById(R.id.profile_section_edit_nationality);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_user_profile_edit, container, false);
}
#Override
public void onClick(View v) {
username_input= editUsername.getText().toString().trim();
age_input = editAge.getText().toString().trim();
nationality_input = editNationality.getText().toString().trim();
//update Firestore data
updateFireStoreData(username_input, age_input, nationality_input);
}
//update the user entered information to the database, if the strings arent empty
public void updateFireStoreData(String nicknameUpdate, String ageUpdate, String nationalityUpdate) {
FirebaseFirestore db = FirebaseFirestore.getInstance();
FirebaseUser currUser = FirebaseAuth.getInstance().getCurrentUser();
DocumentReference userDocRef = db.collection("Users").document(currUser.getDisplayName());
if (!nicknameUpdate.matches("")) {
Map<String, Object> dataUpdate = new HashMap<String, Object>();
dataUpdate.put(NICKNAME, nicknameUpdate);
userDocRef
.set(dataUpdate, SetOptions.merge()).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "Document has been saved");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d(TAG, "Document could not be saved");
}
});
}
}
ERROR LOG:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: MYAPP, PID: 3992
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)'
on a null object reference
at MYAPP.UserProfileFragment$1.onEvent(UserProfileFragment.java:103)
at MYAPP.UserProfileFragment$1.onEvent(UserProfileFragment.java:91)
at com.google.firebase.firestore.DocumentReference.zza(Unknown Source:45)
at com.google.firebase.firestore.zzd.onEvent(Unknown Source:6)
at com.google.android.gms.internal.zzevc.zza(Unknown Source:6)
at com.google.android.gms.internal.zzevd.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:251)
at android.app.ActivityThread.main(ActivityThread.java:6563)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
This is not a Firebase database Exception, either a Cloud Firestore Exception. Your Exception tells you clearly what is going on. So you are attempting to use findViewById() method on a null object reference. This means that getView() returns null. And this is happening because you are calling that method after you are returning the fragmnet view.
In order to solve this, call those methods before and use findViewById() method directly on the view.
One of the activities (Activity A) I have in the application displays a list of videos as you can see in the image:
The videos are stored in an ArrayList called videosList, when the user select a video the video is played using an embedded YouTube player in another activity B.
The problem is when the user goes back from activity B (The activity with the video player) to activity A (The activity with the list of videos) the variable videosList is null so the application stops running with error.
I tried to implement the
protected void onSaveInstanceState(Bundle savedInstanceState) and the
protected void onRestoreInstanceState(Bundle savedInstanceState) methods to save the activity state and some variables so when the user is back to Activity A the application can display the list of videos again, but when I try to gat the values I previously saved in onSaveInstanceState(Bundle savedInstanceState) in the public void onCreate(Bundle savedInstanceState) the savedInstanceStateis always NULL.
Here is my code:
public class VideosCatalogActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
private Toolbar toolbar;
private GridView videosGrid;
private ArrayList<VideoEntity> videosList;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private FirebaseDatabase database;
#Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, " onCreate(Bundle) - Ini ");
super.onCreate(savedInstanceState);
// onSaveInstanceState();
setContentView(R.layout.videos_catalog_layout);
toolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
toolbar.setTitle(R.string.app_name);
toolbar.setTitleTextColor(getResources().getColor(R.color.com_facebook_button_background_color_focused));
mAuth = FirebaseAuth.getInstance();
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = mAuth.getCurrentUser();
}
};
database = FirebaseDatabase.getInstance();
Bundle bundle = getIntent().getExtras();
String actividad = bundle.getString("Activity");
if (actividad.equals("DocumentariesCategoriesActivity")) {
videosList = bundle.getParcelableArrayList("com.app.example.VideoEntity");
updateCatalog();
/*
String videoId = "";
if (!videosList.isEmpty() && !videosList.equals(null)) {
for (VideoEntity video : videosList) {
DatabaseReference mRef = database.getReference().child("Videos").child(video.getId());
mRef.setValue(video);
}
videosGrid = (GridView) findViewById(R.id.videosGrid);
MyGridViewAdapter adapter = new MyGridViewAdapter(this);
adapter.setVideosList(videosList);
videosGrid.setAdapter(adapter);
videosGrid.setOnItemClickListener(this);
} */
}
Log.d(TAG, " onCreate(Bundle) - Fi ");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.d(TAG, "onCreateOptionsMenu(Menu) - Ini");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
Log.d(TAG, "onCreateOptionsMenu(Menu) - Fi");
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
Log.d(TAG, "onOptionItemSelected(MenuItem) - Ini");
switch (menuItem.getItemId()) {
case R.id.action_logout:
updateActivity(mAuth.getCurrentUser());
}
Log.d(TAG, "onOptionItemSelected(MenuItem) - Fi");
return true;
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d(TAG, " onItemClick(AdapterView<?>, View, int, long) - Ini ");
Intent intent = new Intent(getApplicationContext(), YoutubePlayerActivity.class);
intent.putExtra("VIDEO_ID", videosList.get(position).getId());
startActivity(intent);
Log.d(TAG, " onItemClick(AdapterView<?>, View, int, long) - Fi ");
}
protected void updateActivity(FirebaseUser user) {
Log.d(TAG, "updateActivity(FirebaseUser) - Ini");
mAuth.signOut();
Intent i = new Intent(VideosCatalogActivity.this, LoginActivity.class);
startActivity(i);
Log.d(TAG, "updateActivity(FirebaseUser) - Fi");
}
#Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
Log.d(TAG, "onSaveInstanceState(Bundle) - Ini");
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putParcelableArrayList("VIDEOS_LIST", videosList);
savedInstanceState.putAll(savedInstanceState);
Log.d(TAG, "onSaveInstanceState(Bundle) - Fi");
Log.i("","onSaveInstance is executed");
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.d(TAG, "onRestoreInstanceState(Bundle) - Ini");
super.onRestoreInstanceState(savedInstanceState);
videosList = savedInstanceState.getParcelableArrayList("VIDEOS_LIST");
updateCatalog();
Log.i("","onRestoreInstance is executed");
Log.d(TAG, "onRestoreInstanceState(Bundle) - Fi");
}
protected void updateCatalog() {
Log.d(TAG, "updateCatalog() - Ini");
String videoId = "";
for (VideoEntity video : videosList) {
DatabaseReference mRef = database.getReference().child("Videos").child(video.getId());
mRef.setValue(video);
}
videosGrid = (GridView) findViewById(R.id.videosGrid);
MyGridViewAdapter adapter = new MyGridViewAdapter(this);
adapter.setVideosList(videosList);
videosGrid.setAdapter(adapter);
videosGrid.setOnItemClickListener(this);
Log.d(TAG, "updateCatalog() - Fi");
}
}
Any idea how can i solve this problem please ?
Why dont you use a SingletonData class? that stores the ArrayList and when you need to reload the ArrayList you load it from the Singleton.
public class DataSingleton {
private static DataSingleton instance = new DataSingleton();
private DataSingleton(){ }
public static DataSingleton getInstance(){ return instance; }
public static void setIntances(DataSingleton instance){DataSingleton.instance = instance;}
private ArrayList<Videos> videosList;
public void setArrayVideos(ArrayList<Videos> videos){
videosList=videos;
}
public ArrayList<Videos> getArrayVideos(){
return videosList;
}
}
then you call the class in the activity A and set the ArrayList wherever you want.
DataSingleton.getInstance().setArrayVideos(videosList);
videosList= DataSingleton.getInstance().getArrayVideos();
Your onSaveInstanceState implementation must be like this
#Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
Log.d(TAG, "onSaveInstanceState(Bundle) - Ini");
if(savedInstanceState == null)
{
savedInstanceState = new Bundle();
}
savedInstanceState.putParcelableArrayList("VIDEOS_LIST", videosList);
Log.d(TAG, "onSaveInstanceState(Bundle) - Fi");
Log.i("","onSaveInstance is executed");
super.onSaveInstanceState(savedInstanceState);
}