RecyclerView doesn't refresh after Firebase update - java

I have a RecyclerView and for each item, you can start the EditActivity (for Result) to update your text with Firebase.
The problem is that when you come back to the RecyclerView, data is not refreshed
Here's code from my adapter :
holder.editBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent edit_intent = new Intent(holder.authorText.getContext(), EditActivity.class);
edit_intent.putExtra("text", textList.get(position).getBody());
edit_intent.putExtra("id", textList.get(position).textId);
((Activity) context).startActivityForResult(edit_intent, 1);
}
});
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == RESULT_OK){
notifyDataSetChanged();
}
}
}
Here's code from my EditActivity :
edit_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mProgress.setVisibility(View.VISIBLE);
edit_btn.setVisibility(View.INVISIBLE);
String new_text = edit_text.getText().toString();
mFirestore.collection("Text").document(text_id).update("body", new_text).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
Toast.makeText(EditActivity.this, R.string.changes, Toast.LENGTH_LONG).show();
Intent intent = new Intent();
intent.putExtra("newText", new_text);
setResult(RESULT_OK, intent);
finish();
}
else{
String error = task.getException().getMessage();
Toast.makeText(EditActivity.this, R.string.error + error, Toast.LENGTH_LONG).show();
}
mProgress.setVisibility(View.INVISIBLE);
edit_btn.setVisibility(View.VISIBLE);
}
});
}
});
How to refresh the RecyclerView and setText with the new Text ?
I would be very grateful for your help :)

There are few things you're doing wrong.
Pass the clickedItem position to EditActivity to update it later on.
holder.editBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent edit_intent = new Intent(holder.authorText.getContext(), EditActivity.class);
edit_intent.putExtra("text", textList.get(position).getBody());
edit_intent.putExtra("id", textList.get(position).textId);
edit_intent.putExtra("position", position);
((Activity) context).startActivityForResult(edit_intent, 1);
}
});
In EditActivity, Save the position in a variable & Return it back with new text
setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mProgress.setVisibility(View.VISIBLE);
edit_btn.setVisibility(View.INVISIBLE);
String new_text = edit_text.getText().toString();
mFirestore.collection("Text").document(text_id).update("body", new_text).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()){
Toast.makeText(EditActivity.this, R.string.changes, Toast.LENGTH_LONG).show();
Intent intent = new Intent();
intent.putExtra("newText", new_text);
//Return the position s well
intent.putExtra("position", position);
setResult(RESULT_OK, intent);
finish();
}
else{
String error = task.getException().getMessage();
Toast.makeText(EditActivity.this, R.string.error + error, Toast.LENGTH_LONG).show();
}
mProgress.setVisibility(View.INVISIBLE);
edit_btn.setVisibility(View.VISIBLE);
}
});
}
});
override onActivityResult() in your adaptor's parent activity
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
if(resultCode == RESULT_OK){
String newText = data.getStringExtra("newText");
int itemPosition = data.getIntExtra("position");
//Pass these values to adapter through `updateItem` method
adapter.updateItem(newText, itemPosition);
}
}
}
Define the updateItem method inside adapter class
public void updateItem(String newData, int index)
{
textList.set(index, newData);
adapter.notifyItemChanged(index);
}
Cheers :)

Related

Call adapter.notifyItemChanged(position); working so weird

I have a list that I get from firebase, this list is about posts and what I need is when user like it or unlike it, the list updated through adapter. as I used recyclerview and adapter to show my data after receiving it from firebase. Actually, everything works so fine with me but just this issue when user like or unlike the post it goes crazy. I tried to make a toast to make sure that I'm working with the same position as I expected and it proved me right.
the photo of the post appears and disappears by clicking like button like the vides shows and it does not updating the data in a proper way like it mess with the number of likes
You can find my code below with a video to illustrate the problem I am facing.
I hope somebody can help me out.
private void read_posts() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
//post_models.clear();
Post_Model post_model = dataSnapshot.getValue(Post_Model.class);
post_models.add(post_model);
post_adapter = new Post_Adapter(post_models, getContext());
recyclerviewNewsfeed.setAdapter(post_adapter);
progressBar.setVisibility(View.GONE);
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Post_Model post_model = dataSnapshot.getValue(Post_Model.class);
for (int i=0;i<post_models.size();i++){
if(post_models.get(i).getId().equals(post_model.getId())){
post_models.set(i,post_model);
post_adapter.notifyItemChanged(i);
break;
}
}
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
It's my post adapter
public class Post_Adapter extends RecyclerView.Adapter<Post_Adapter.Viewholder> {
private Context context;
private List<Post_Model> post_models;
FirebaseUser firebaseUser;
List<Like_Model> like_modelList, likeblue_modelList;
View_Photos_Adapter view_Photos_adapter;
boolean userlikeit;
public static int positionn=-1;
public Post_Adapter(List<Post_Model> post_models, Context context) {
this.context = context;
this.post_models = post_models;
}
#NonNull
#Override
public Viewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.post_item, parent, false);
return new Viewholder(view);
}
#SuppressLint("SetTextI18n")
#Override
public void onBindViewHolder(#NonNull final Viewholder holder, final int position) {
final Post_Model post_model = post_models.get(position);
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference referencee = FirebaseDatabase.getInstance().getReference("Posts").child(post_model.getId());
referencee.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
//Toast.makeText(CommentActivity.this, post_id+"", Toast.LENGTH_SHORT).show();
Post_Model post_modell = dataSnapshot.getValue(Post_Model.class);
// Toast.makeText(CommentActivity.this, post_id+"", Toast.LENGTH_SHORT).show();
if (post_modell.getLikeModels() != null) {
for (int i = 0; i < post_modell.getLikeModels().size(); i++) {
if (post_modell.getLikeModels().get(i).getUserid().equals(firebaseUser.getUid())) {
userlikeit = true;
break;
} else {
userlikeit = false;
}
}
} else {
userlikeit = false;
}
//snapshot.getRef().removeValue();
// Toast.makeText(context, userlikeit+"58", Toast.LENGTH_SHORT).show();
//Toast.makeText(CommentActivity.this, comment_models.size()+"", Toast.LENGTH_SHORT).show();
if (userlikeit) {
holder.likebluebtn.setVisibility(View.VISIBLE);
holder.likebtn.setVisibility(View.GONE);
} else {
holder.likebtn.setVisibility(View.VISIBLE);
holder.likebluebtn.setVisibility(View.GONE);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
if (post_model.getUserid().equals(firebaseUser.getUid())) {
holder.editbtn.setVisibility(View.VISIBLE);
holder.deletebtn.setVisibility(View.VISIBLE);
} else {
holder.editbtn.setVisibility(View.GONE);
holder.deletebtn.setVisibility(View.GONE);
}
holder.editbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.postTextView.setVisibility(View.GONE);
holder.postEditText.setVisibility(View.VISIBLE);
holder.postEditText.setText(post_model.getPost());
holder.editbtn.setVisibility(View.GONE);
holder.savebtn.setVisibility(View.VISIBLE);
}
});
holder.savebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Post_Model post_modell = new Post_Model(post_model.getId(), post_model.getUserid()
, holder.postEditText.getText().toString(), post_model.getTime()
, post_model.getCommentModels(), post_model.getPostphotos(), post_model.getLikeModels());
FirebaseDatabase.getInstance().getReference("Posts")
.child(post_model.getId())
.setValue(post_modell);
holder.postTextView.setVisibility(View.VISIBLE);
holder.postEditText.setVisibility(View.GONE);
holder.editbtn.setVisibility(View.VISIBLE);
holder.savebtn.setVisibility(View.GONE);
Toast.makeText(context, "Post has been edited successfully", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context, NewsfeedActivity.class);
context.startActivity(intent);
((Activity) context).overridePendingTransition(R.anim.slide_in_right, R.anim.slide_in_left);
((Activity) context).finish();
}
});
holder.deletebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new AlertDialog.Builder(context)
.setTitle("Delete Post")
.setMessage("Are you sure you want to delete this post?")
// Specifying a listener allows you to take an action before dismissing the dialog.
// The dialog is automatically dismissed when a dialog button is clicked.
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final DatabaseReference referencee = FirebaseDatabase.getInstance().getReference("Posts")
.child(post_model.getId());
referencee.removeValue();
Toast.makeText(context, "Post deleted successfully", Toast.LENGTH_LONG).show();
Intent intent = new Intent(context, NewsfeedActivity.class);
context.startActivity(intent);
((Activity) context).overridePendingTransition(R.anim.slide_in_right, R.anim.slide_in_left);
((Activity) context).finish();
}
})
// A null listener allows the button to dismiss the dialog and take no further action.
.setNegativeButton(android.R.string.no, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
});
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
like_modelList = new ArrayList<>();
likeblue_modelList = new ArrayList<>();
//Toast.makeText(context, read_likes(post_model.getId())+"", Toast.LENGTH_SHORT).show();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
User user = snapshot.getValue(User.class);
// Toast.makeText(Create_Coworking_SpaceActivity.this, "111111111", Toast.LENGTH_LONG).show();
if (user.getId().equals(post_model.getUserid())) {
if (user.getImageURL().equals("default")) {
holder.userImage.setImageResource(R.drawable.ic_imgprofile);
} else {
Glide.with(holder.itemView).load(user.getImageURL()).into( holder.userImage);
}
holder.username.setText(user.getUsername());
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
if (post_model.getPostphotos() == null) {
holder.postPhotosRC.setVisibility(View.GONE);
} else {
holder.postPhotosRC.setHasFixedSize(true);
holder.postPhotosRC.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
view_Photos_adapter = new View_Photos_Adapter(post_model.getPostphotos(), context);
holder.postPhotosRC.setAdapter(view_Photos_adapter);
}
holder.postTextView.setText(post_model.getPost());
holder.posttimeTextView.setText(post_model.getTime());
holder.commentbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, CommentActivity.class);
intent.putExtra("post_id", post_model.getId());
context.startActivity(intent);
((Activity) context).overridePendingTransition(R.anim.slide_in_right, R.anim.slide_in_left);
}
});
if (post_model.getCommentModels() != null) {
holder.numofcommentsEditText.setText(post_model.getCommentModels().size() + "");
holder.numofcommentsTextView.setText(post_model.getCommentModels().size() + "");
}
final int[] li = {0};
holder.likebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
like(post_model.getId());
// Post_Adapter.this.notifyItemChanged(position);
positionn=position;
}
});
holder.likebluebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Toast.makeText(context, userlikeit+"5", Toast.LENGTH_SHORT).show();
unlike(post_model.getId());
// Post_Adapter.this.notifyItemChanged(position);
positionn=position;
}
});
if (post_model.getLikeModels() != null) {
holder.numoflikesEditText.setText(post_model.getLikeModels().size() + "");
holder.numoflikesTextView.setText(post_model.getLikeModels().size() + "");
}
holder.likesTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, LikeActivity.class);
intent.putExtra("post_id", post_model.getId());
context.startActivity(intent);
((Activity) context).overridePendingTransition(R.anim.slide_in_right, R.anim.slide_in_left);
}
});
holder.commentsTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, CommentActivity.class);
intent.putExtra("post_id", post_model.getId());
context.startActivity(intent);
((Activity)
context).overridePendingTransition(R.anim.slide_in_right,
R.anim.slide_in_left);
}
});
}
#Override
public int getItemCount() {
return post_models == null ? 0 : post_models.size();
}

URL Result from QR Code Scanner only show text

I'm new at programming and I tried to build QR Code Scanner app. My problem is in the Scanner, I can't have the result clickable even though the QR Code contains URL link on it. It just shows a pop-up text.
Here's my code:
Scanner:
public class ReaderActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reader);
Button scan_btn = findViewById(R.id.scan_btn);
final Activity activity = this;
IntentIntegrator qrScan = new IntentIntegrator(this);
scan_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
IntentIntegrator integrator = new IntentIntegrator(activity);
integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES);
integrator.setPrompt("Scan");
integrator.setCameraId(0);
integrator.setBeepEnabled(false);
integrator.setBarcodeImageEnabled(false);
integrator.initiateScan();
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if(result != null){
if(result.getContents()==null){
Toast.makeText(this, "You cancelled the scanning", Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(this, result.getContents(), Toast.LENGTH_LONG).show();
}
}
else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
Can anybody fix this?

URL result in scanner

I'm still new at programming and I tried to build a code scanner for my project.
The problem is the result only show a text. It can't be click or direct to browser.
public class ReaderActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reader);
Button scan_btn = findViewById(R.id.scan_btn);
final Activity activity = this;
IntentIntegrator qrScan = new IntentIntegrator(this);
scan_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
IntentIntegrator integrator = new IntentIntegrator(activity);
integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES);
integrator.setPrompt("Scan");
integrator.setCameraId(0);
integrator.setBeepEnabled(false);
integrator.setBarcodeImageEnabled(false);
integrator.initiateScan();
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if(result != null){
if(result.getContents()==null){
Toast.makeText(this, "You cancelled the scanning", Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(this, result.getContents(), Toast.LENGTH_LONG).show();
}
}
else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
can somebody fix this?
you can check if result.getContents() start with "http" or "https" use string.indexOf, get it and put to your browser.

App closes after clicking a button instead of returning to main activity

I am using startActivityForResult() [in MainActivity class] to call another activity called "EditActivity" & get some edited values back to the MainActivity. EditActivity has a button which when pressed should return the user to the MainActivity. But instead the app is closing on button-press.
Inside MainActivity :
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, EditActivity.class);
intent.putExtra("edit_data", arrayList.get(position).toString());
intent.putExtra("edit_position", position);
startActivityForResult(intent, IntentValuesClass.REQUEST_CODE);
}
});
Inside EditActivity:
saveButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent data=new Intent();
data.putExtra("edited_text",editInput);
data.putExtra("position",pos);
setResult(EditActivity.RESULT_OK,data);
Log.w(IntentValuesClass.Msg,"Button SAVE Clicked");
finish();
Log.w(IntentValuesClass.Msg,"finished");
}
}
);
Again on returning to MainActivity:
#Override
protected void onActivityResult( int requestCode, int resultCode, Intent data){
Log.w(IntentValuesClass.Msg,"Inside onActivityResult");
int position;
if (requestCode == IntentValuesClass.REQUEST_CODE) {
if (resultCode==EditActivity.RESULT_OK) {
Log.w(IntentValuesClass.Msg,"Result ok");
String s = data.getStringExtra("edited_text");
position = data.getIntExtra("position",-1);
arrayList.remove(position);
arrayList.add(position, s);
adapter.notifyDataSetChanged();
}
}
}
put the finish() at the end of your method.
public void onClick(View v) {
Intent data=new Intent();
data.putExtra("edited_text",editInput);
data.putExtra("position",pos);
setResult(EditActivity.RESULT_OK,data);
Log.w(IntentValuesClass.Msg,"Button SAVE Clicked");
Log.w(IntentValuesClass.Msg,"finished");
finish();
}

how pass result from alertDialog to onActivityResult

I have Activity_A an Activity_B.
I use onActivityResult and i have a problem:
java.lang.RuntimeException: Failure delivering result
ResultInfo{who=null, request=3, result=-1, data=Intent { (has extras)
}} to activity {com.example.sellcar/com.example.sellcar.View_Offer}:
android.database.CursorIndexOutOfBoundsException: Index 0 requested,
with a size of 0
I guess that I can not pass this way 'result' from alertDialog to onActivityResult.
I do not know how to solve this problem :/
Please help
Activity_A:
bBUTTON.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Activity_A.this,Activity_B.class);
startActivityForResult(intent, 3);
}
});
...
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 3 && resultCode == RESULT_OK){
String pId = data.getStringExtra("MyData");
Toast.makeText(Activity_A.this,pId,Toast.LENGTH_LONG).show();
}
}
Activity_B:
AlertDialog.Builder builder=new AlertDialog.Builder(View_Sell.this);
builder.setTitle("UWAGA !").setMessage("blablabla");
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
String ostatnioDodanaSprzedaz="XYZ";
Intent intent = new Intent();
intent.putExtra("MyData", ostatnioDodanaSprzedaz);
setResult(RESULT_OK, intent);
onBackPressed();
} });
builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
} });
AlertDialog ad = builder.create();
ad.show();
Try to replace:
setResult(RESULT_OK, intent);
onBackPressed();
on:
if (getParent() == null) {
setResult(RESULT_OK, intent);
} else {
getParent().setResult(RESULT_OK, intent);
}
finish();
You can follow the Observer pattern.
First, create an Interface in the Activity class itself:
public interface ResultListener {
void onResultSet(String text);
}
Then, create an object of ResultListener globally:
ResultListener = rl;
Implement the onResultSet(String text) method inside the onCreate method:
rl = new ResultListener() {
#Override
public void onPositiveResult(String text) {
Toast.makeText(context, text, Toast.LENGTH_LONG).show();
}
};
Next, create the AlertDialog
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("UWAGA !").setMessage("blablabla");
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
String ostatnioDodanaSprzedaz="XYZ";
tl.onResultSet(ostatnioDodanaSprzedaz);
// onBackPressed();
} });
builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
} });
builder.show();
Here's how the final code will look:
public class MainActivity extends Activity {
ResultListener rl;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
rl = new ResultListener() {
#Override
public void onPositiveResult(String text) {
Toast.makeText(context, text, Toast.LENGTH_LONG).show();
}
};
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setTitle("UWAGA !").setMessage("blablabla");
builder.setPositiveButton("YES", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
String ostatnioDodanaSprzedaz="XYZ";
rl.onResultSet(ostatnioDodanaSprzedaz);
// onBackPressed();
} });
builder.setNegativeButton("NO", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
} });
builder.show();
} //onCreate closed
public interface ResultListener {
void onResultSet(String text);
}
} //MainActivity Class closed

Categories