I'm working on a chat app. In this app I want to sort contact lists with latest message timestamp.
adapter = new ContactListAdapter(ob1, getActivity(), fusername);
if (!adapted) {
chatLists.setAdapter(adapter);
adapted = true;
}else {
adapter.updateList(ob1, getActivity(), fusername);
}
Here setAdapter works fine and updating the complete recyclerview with setAdapter works fine too. But it reloads the complete view with all data like image and user message. So I just want to refresh the index without loading all data again.
On the above code. adapted is a boolean value. It's initial value is false. And after setting the adapter initial value changes to true. Then to update the adapter I call updateList function.
public class ContactListAdapter extends RecyclerView.Adapter<ContactListAdapter.viewHolder>{
com.google.firebase.database.DataSnapshot d;
Context c;
JsonParser parser = new JsonParser();
String username;
ArrayList<ChatroomLists> ob1 = new ArrayList<ChatroomLists>();
public ContactListAdapter(ArrayList<ChatroomLists> ob1, Context c, String fusername) {
this.c = c;
this.username = fusername;
this.ob1.addAll(ob1);
}
public void updateList(ArrayList<ChatroomLists> ob1, Context c, String fusername) {
this.ob1.clear();
this.ob1.addAll(ob1);
this.notifyDataSetChanged();
}
public class viewHolder extends RecyclerView.ViewHolder {
CircleImageView user_img;
ImageView message_stats;
TextView user_name;
TextView user_message;
TextView timestamp;
CircleImageView unreadbadge;
public viewHolder(View itemView) {
super(itemView);
user_img = (CircleImageView) itemView.findViewById (R.id.user_img_list);
user_name = (TextView) itemView.findViewById (R.id.contact_name);
user_message = (TextView) itemView.findViewById (R.id.user_message);
message_stats = (ImageView) itemView.findViewById (R.id.message_status);
timestamp = (TextView)itemView.findViewById(R.id.time);
unreadbadge = (CircleImageView) itemView.findViewById(R.id.unread);
}
}
#Override
public viewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from (parent.getContext ()).inflate (R.layout.chat_list_style, parent, false);
return new viewHolder(v);
}
#Override
public void onBindViewHolder(viewHolder holder, int position) {
ChatroomLists chatroomLists = ob1.get(position);
Iterator<ChatroomLists> iter = ob1.iterator();
String id = chatroomLists.getId();
String time = chatroomLists.getTimestamp();
Handler h = new Handler();
FirebaseDatabase.getInstance().getReference().child("unread").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("chatrooms").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
try{
if (dataSnapshot.hasChild(id)){
holder.unreadbadge.setVisibility(View.VISIBLE);
}else {
holder.unreadbadge.setVisibility(View.GONE);
}
}catch (Exception e){
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
try{
long mtime = TimeUnit.MILLISECONDS.toMinutes(System.currentTimeMillis())-TimeUnit.MILLISECONDS.toMinutes(Long.parseLong(time));
if (mtime<60){
holder.timestamp.setText(String.valueOf(mtime)+ " mins");
if (mtime==1)
holder.timestamp.setText(1+ " min");
else if (mtime<1){
holder.timestamp.setText("Just Now");
}
else
holder.timestamp.setText(mtime+ " mins");
}
else if (mtime>60 && mtime<1440){
if (mtime/60==1)
holder.timestamp.setText(String.valueOf(mtime/60)+ " hour");
else
holder.timestamp.setText(String.valueOf(mtime/60)+ " hours");
}
else if (mtime>=1440&&mtime<10080){
if (mtime/1440==1)
holder.timestamp.setText(String.valueOf(mtime/1440)+ " day");
else
holder.timestamp.setText(String.valueOf(mtime/1440)+ " days");
}else if(mtime>10080&&mtime<3679200){
if (mtime/10080==1)
holder.timestamp.setText(String.valueOf(mtime/10080)+ " week");
else
holder.timestamp.setText(String.valueOf(mtime/10080)+ " weeks");
}else if(mtime>3679200){
if (mtime/3679200==1)
holder.timestamp.setText(String.valueOf(mtime/3679200)+ " year");
else
holder.timestamp.setText(String.valueOf(mtime/3679200)+ " years");
}
}catch (Exception e){
}
h.postDelayed(this,60000);
}
},60000);
FirebaseDatabase.getInstance().getReferenceFromUrl("https://droidchatz.firebaseio.com/groupchat/" + id + "/chat").limitToLast(1).addValueEventListener(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
for (com.google.firebase.database.DataSnapshot d: dataSnapshot.getChildren()){
if (dataSnapshot.child(d.getKey()).child("type").getValue(String.class).equals("text"))
holder.user_message.setText (dataSnapshot.child(d.getKey()).child("message").getValue(String.class));
else if(dataSnapshot.child(d.getKey()).child("type").getValue(String.class).equals("video"))
holder.user_message.setText ("New Video Message");
else if(dataSnapshot.child(d.getKey()).child("type").getValue(String.class).equals("image"))
holder.user_message.setText ("New Image Message");
else if(dataSnapshot.child(d.getKey()).child("type").getValue(String.class).equals("gif"))
holder.user_message.setText ("New GIF Message");
else if(dataSnapshot.child(d.getKey()).child("type").getValue(String.class).equals("file"))
holder.user_message.setText ("New Document");
else {
holder.user_message.setText (dataSnapshot.child(d.getKey()).child("message").getValue(String.class));
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
FirebaseDatabase.getInstance().getReferenceFromUrl("https://droidchatz.firebaseio.com/groups/"+id+"/image").addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
try{
Glide
.with(c)
.load(dataSnapshot.getValue(String.class))
.asBitmap()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.dontAnimate()
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap arg0, GlideAnimation<? super Bitmap> arg1) {
holder.user_img.setImageBitmap(arg0);
}});
}catch (Exception e){
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
holder.user_name.setText (id);
holder.itemView.setOnClickListener (new View.OnClickListener () {
#Override
public void onClick(View v) {
Intent intent = new Intent (c, ChatRoom.class);
intent.putExtra("username",username);
intent.putExtra ("group_name", id);
c.startActivity (intent);
}
});
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getItemCount() {
return ob1.size();
}
}
So what am I doing wrong?
You just have to add values to your ob1 object and call adapter.notifyDataSetChanged(); to update your list.
Initialize your adapter only once and populate the ob1 list.
You are storing your activity ArrayList reference into your adapter ArrayList reference:
this.ob1 = ob1;
change in your adapter constructor, try it once:
public ContactListAdapter(ArrayList<ChatroomLists> ob1, Context c, String fusername) {
this.c = c;
this.username = fusername;
this.ob1.addAll(ob1);
}
Related
I'm having a problem, that maybe we can solve it and help the community. I have made an Adapter for my RecyclerView and I have created a listener for the constraint layout in order to remove one element of the list. As you can see in the code the delete message works well but I don't know how to update the RecyclerView from the AccountFragment (the one that's using this adapter). Does anyone know how to notify that changes?
AccountFragment:
public class AccountFragment extends Fragment {
private TextView textViewUserProfileUsername;
private TextView textViewUserProfileDescription;
private ImageButton imageButtonAccountEdit;
private EditText editTextAccountDescription;
private RecyclerView recyclerViewUserProfileComments;
private TextView textViewUserProfileNoComments;
private ImageView imageViewUserProfileSendMessage;
private EditText editTextUserProfileSendMessage;
private final Gson gson = new Gson();
private User userLocal;
private SharedPreferences sharedPreferences;
private Context context;
private AlertDialog dialog;
private String previousDescription;
private AccountCommentsAdapter accountCommentsAdapter;
private final List<UserComments> userCommentsList = new ArrayList<>();
public AccountFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = getActivity();
assert context != null;
sharedPreferences = context.getSharedPreferences(Constants.sharedPreferencesDocName, Context.MODE_PRIVATE);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_account, container, false);
}
#Override
public void onViewCreated(#NonNull #NotNull View view, #Nullable #org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
bindUI(view);
setListeners();
userLocal = gson.fromJson(sharedPreferences.getString("user", ""), User.class);
showUserInformation();
setAdapter();
}
private void bindUI(View view) {
textViewUserProfileUsername = view.findViewById(R.id.textViewUserProfileUsername);
textViewUserProfileDescription = view.findViewById(R.id.textViewUserProfileDescription);
imageButtonAccountEdit = view.findViewById(R.id.imageButtonAccountEdit);
recyclerViewUserProfileComments = view.findViewById(R.id.recyclerViewUserProfileComments);
textViewUserProfileNoComments = view.findViewById(R.id.textViewUserProfileNoComments);
imageViewUserProfileSendMessage = view.findViewById(R.id.imageViewUserProfileSendMessage);
editTextUserProfileSendMessage = view.findViewById(R.id.editTextUserProfileSendMessage);
}
private void setListeners() {
imageButtonAccountEdit.setOnClickListener(v -> showEditDescriptionDialog());
imageViewUserProfileSendMessage.setOnClickListener(view -> {
if (!TextUtils.isEmpty(editTextUserProfileSendMessage.getText().toString())) {
final Date currentTime = new Date();
#SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
TimeZone timeZone = simpleDateFormat.getTimeZone();
simpleDateFormat.setTimeZone(timeZone);
String date = simpleDateFormat.format(currentTime);
final UserComments userCommentsToAdd = new UserComments(userLocal.getId(), userLocal.getId(), userLocal.getUsername(), userLocal.getUsername(), editTextUserProfileSendMessage.getText().toString().trim(), date);
editTextUserProfileSendMessage.setText("");
addComment(userCommentsToAdd);
}
});
}
private void showUserInformation() {
textViewUserProfileUsername.setText(userLocal.getUsername());
textViewUserProfileDescription.setText(userLocal.getDescription());
getUserComments();
}
private void showEditDescriptionDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(getString(R.string.edit_description));
final View customLayout = getLayoutInflater().inflate(R.layout.alert_dialog_edit_account, null);
builder.setView(customLayout);
dialog = builder.create();
editTextAccountDescription = customLayout.findViewById(R.id.editTextAccountDescription);
if (userLocal.getDescription() != null) {
editTextAccountDescription.setText(userLocal.getDescription());
previousDescription = editTextAccountDescription.getText().toString();
}
Button buttonAccountCancelDescription = customLayout.findViewById(R.id.buttonAccountCancelDescription);
Button buttonAccountSaveDescription = customLayout.findViewById(R.id.buttonAccountSaveDescription);
buttonAccountSaveDescription.setOnClickListener(v -> saveUserDescription());
buttonAccountSaveDescription.setOnClickListener(v -> {
if (editTextAccountDescription.getText().toString().length() <= 150) {
saveUserDescription();
} else {
setErrors(2);
}
});
editTextAccountDescription.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() > 150) {
setErrors(2);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
buttonAccountCancelDescription.setOnClickListener(v -> dialog.dismiss());
dialog.setCancelable(false);
dialog.show();
}
private void saveUserDescription() {
if (!editTextAccountDescription.getText().toString().isEmpty()) {
if (!editTextAccountDescription.getText().toString().equals(previousDescription)) {
userLocal.setDescription(editTextAccountDescription.getText().toString());
sharedPreferences.edit().putString("user", gson.toJson(userLocal)).apply();
Thread thread = new Thread() {
#Override
public void run() {
Response response;
try {
response = UserRequests.editUserDescription(userLocal.getId(), userLocal.getDescription());
if (response.code() == 200) {
String responseBody = Objects.requireNonNull(response.body()).string();
responseBody = responseBody.replace("\r\n", "");
if (responseBody.contains("1")) {
updateDescription();
} else if (responseBody.contains("2")) {
updateDescription();
} else {
setErrors(1);
}
} else {
setErrors(1);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
thread.start();
} else {
setErrors(4);
}
} else {
setErrors(3);
}
}
private void updateDescription() {
Thread thread = new Thread() {
public void run() {
requireActivity().runOnUiThread(() -> {
textViewUserProfileDescription.setText(userLocal.getDescription());
dialog.dismiss();
});
}
};
thread.start();
}
private void setErrors(int error) {
switch (error) {
case 1:
Thread thread = new Thread() {
public void run() {
requireActivity().runOnUiThread(() -> Toast.makeText(context, getString(R.string.generic_error), Toast.LENGTH_SHORT).show());
}
};
thread.start();
break;
case 2:
editTextAccountDescription.setError(getString(R.string.description_length));
editTextAccountDescription.requestFocus();
break;
case 3:
editTextAccountDescription.setError(getString(R.string.required_field));
editTextAccountDescription.requestFocus();
break;
case 4:
dialog.dismiss();
break;
}
}
private void setAdapter() {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context);
linearLayoutManager.setStackFromEnd(true);
recyclerViewUserProfileComments.setLayoutManager(linearLayoutManager);
recyclerViewUserProfileComments.scrollToPosition(userCommentsList.size() - 1);
}
private void displayMessages() {
if (userCommentsList.size() > 0) {
Thread thread = new Thread() {
public void run() {
requireActivity().runOnUiThread(() -> {
if (recyclerViewUserProfileComments.getVisibility() == View.GONE) {
recyclerViewUserProfileComments.setVisibility(View.VISIBLE);
}
if (textViewUserProfileNoComments.getVisibility() == View.VISIBLE) {
textViewUserProfileNoComments.setVisibility(View.GONE);
}
accountCommentsAdapter = new AccountCommentsAdapter(context, userCommentsList);
recyclerViewUserProfileComments.setAdapter(accountCommentsAdapter);
recyclerViewUserProfileComments.scrollToPosition(userCommentsList.size() - 1);
accountCommentsAdapter.notifyDataSetChanged();
});
}
};
thread.start();
} else {
Thread thread = new Thread() {
public void run() {
requireActivity().runOnUiThread(() -> {
recyclerViewUserProfileComments.setVisibility(View.GONE);
textViewUserProfileNoComments.setVisibility(View.VISIBLE);
});
}
};
thread.start();
}
}
private void addComment(UserComments userCommentsToAdd) {
Thread thread = new Thread() {
#Override
public void run() {
Response response;
try {
response = UserCommentsRequests.addUserComment(userCommentsToAdd);
if (response.code() == 200) {
String responseBody = Objects.requireNonNull(response.body()).string();
responseBody = responseBody.replace("\r\n", "");
if (responseBody.contains("1")) {
userCommentsList.add(userCommentsToAdd);
userCommentsList.clear();
getUserComments();
}
} else if (response.code() == 204) {
displayMessages();
} else {
setErrors(1);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
thread.start();
}
private void getUserComments() {
Thread thread = new Thread() {
#Override
public void run() {
Response response;
try {
response = UserCommentsRequests.getUserComments(userLocal.getId());
if (response.code() == 200) {
String responseBody = Objects.requireNonNull(response.body()).string();
responseBody = responseBody.replace("\r\n", "");
JSONArray responseArray = new JSONArray(responseBody);
for (int i = 0; i < responseArray.length(); i++) {
String jsonObjectString = responseArray.getJSONObject(i).toString();
userCommentsList.add(gson.fromJson(jsonObjectString, UserComments.class));
}
displayMessages();
} else if (response.code() == 204) {
displayMessages();
} else {
setErrors(1);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
thread.start();
}
}
AccountCommentsAdapter:
public class AccountCommentsAdapter extends RecyclerView.Adapter<AccountCommentsAdapter.AccountCommentsAdapterViewHolder> {
private final Context context;
List<UserComments> userCommentsList;
public static final int MSG_TYPE_LEFT = 0;
public static final int MSG_TYPE_RIGHT = 1;
public AccountCommentsAdapter(Context context, List<UserComments> userCommentsList) {
this.context = context;
this.userCommentsList = userCommentsList;
}
#NonNull
#NotNull
#Override
public AccountCommentsAdapterViewHolder onCreateViewHolder(#NonNull #NotNull ViewGroup parent, int viewType) {
View view;
if (viewType == MSG_TYPE_RIGHT) {
view = LayoutInflater.from(context).inflate(R.layout.fragment_chat_message_sent, parent, false);
} else {
view = LayoutInflater.from(context).inflate(R.layout.fragment_chat_message_received, parent, false);
}
return new AccountCommentsAdapterViewHolder(view);
}
#Override
public int getItemViewType(int position) {
FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
assert firebaseUser != null;
if (userCommentsList.get(position).getUser_from_username().equals(firebaseUser.getDisplayName())) {
return MSG_TYPE_RIGHT;
} else {
return MSG_TYPE_LEFT;
}
}
#Override
public void onBindViewHolder(#NonNull #NotNull AccountCommentsAdapterViewHolder holder, int position) {
UserComments userComments = userCommentsList.get(position);
int viewType = holder.getItemViewType();
if (viewType == MSG_TYPE_LEFT) {
holder.textViewMessageUsername.setText(userComments.getUser_from_username());
holder.textViewMessageUsername.setOnClickListener(v -> {
Intent intent = new Intent(context, UserProfileActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Bundle bundle = new Bundle();
bundle.putString("userId", userComments.getUser_from_id());
bundle.putString("username", userComments.getUser_from_username());
intent.putExtras(bundle);
context.startActivity(intent);
});
holder.constraintLayoutMessageRight.setOnLongClickListener(v -> {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(R.string.delete_message)
.setPositiveButton(R.string.yes, (dialogInterface, i) -> deleteMessage(position))
.setNegativeButton(R.string.no, (dialogInterface, which) -> dialogInterface.dismiss());
builder.create();
builder.show();
return false;
});
} else {
holder.constraintLayoutMessageRight.setOnLongClickListener(v -> {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(R.string.delete_message)
.setPositiveButton(R.string.yes, (dialogInterface, i) -> deleteMessage(position))
.setNegativeButton(R.string.no, (dialogInterface, which) -> dialogInterface.dismiss());
builder.create();
builder.show();
return false;
});
}
holder.textViewMessageMessage.setText(userComments.getMessage());
holder.textViewMessageTime.setText(userComments.getCreated_time());
}
#Override
public int getItemCount() {
return userCommentsList.size();
}
public static class AccountCommentsAdapterViewHolder extends RecyclerView.ViewHolder {
ConstraintLayout constraintLayoutMessageRight;
TextView textViewMessageMessage;
TextView textViewMessageTime;
TextView textViewMessageUsername;
public AccountCommentsAdapterViewHolder(#NonNull #NotNull View itemView) {
super(itemView);
textViewMessageMessage = itemView.findViewById(R.id.textViewMessageMessage);
textViewMessageTime = itemView.findViewById(R.id.textViewMessageTime);
constraintLayoutMessageRight = itemView.findViewById(R.id.constraintLayoutMessageRight);
textViewMessageUsername = itemView.findViewById(R.id.textViewMessageUsername);
}
}
private void deleteMessage(int position) {
UserComments userCommentsToRemove = userCommentsList.get(position);
Thread thread = new Thread() {
#Override
public void run() {
Response response;
try {
response = UserCommentsRequests.removeUserComments(userCommentsToRemove.getId());
if (response.code() == 200) {
String responseBody = Objects.requireNonNull(response.body()).string();
responseBody = responseBody.replace("\r\n", "");
if (responseBody.contains("1")) {
userCommentsList.remove(position);
// Here it should update the recyclerview in order to notify that element has been removed.
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
};
thread.start();
}
}
UPDATE:
Solved by adding this method and then call it after userCommentsList.remove(position):
private void updateUI(){
Handler mainHandler = new Handler(context.getMainLooper());
Runnable runnable = this::notifyDataSetChanged;
mainHandler.post(runnable);
}
Inside the adapter you can use notifyDataSetChanged()
MY ORIGINAL QUESTION
I am making an android app with firebase Realtime database. I am getting sum of the firebase nodes in side recycler view. I have a text view out side the recycler view where I am getting the sub total of the values of the recycler view. MY PROBLEM is that I cannot get the actual sum and also the sum keeps increasing when I scroll up and down. Here is my Main activity JAVA code:
public class MainActivity extends AppCompatActivity {
FirebaseDatabase myfire;
DatabaseReference myRef;
private FirebaseRecyclerOptions<entry> options;
int totalEarned = 0;
int totalSpent = 0;
int totalSaved=0;
#Override
public void onBackPressed() {
final AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("Are you sure to exit?");
dialog.setPositiveButton("Play", (dialog1, which) -> {
});
dialog.setNegativeButton("Exit", (dialog12, which) -> {
FirebaseAuth.getInstance().signOut();
MainActivity.this.finish();
});
dialog.show();
}
private String getUID() {
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
if (mUser != null) {
String strUID = mUser.getUid();
if (!TextUtils.isEmpty(strUID)) {
return strUID;
}
}
return "";
}
#SuppressLint("SetTextI18n")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//==============
final RecyclerView userlist = (RecyclerView) findViewById(R.id.idRecycleView);
myfire = FirebaseDatabase.getInstance();
userlist.setLayoutManager(new LinearLayoutManager(this));
//==================
final TextView tvTotalIncome = findViewById(R.id.idTotalIncome);
final TextView tvTotalExpanse = findViewById(R.id.idTotalExpanse);
final TextView tvTotalSaved = findViewById(R.id.idTotalSaved);
//==================
final FloatingActionButton btnBudget = findViewById(R.id.idCreateBudget);
myfire = FirebaseDatabase.getInstance();
final String strUID = getUID();
if (TextUtils.isEmpty(strUID)) {
//handle case of null UID
}
final Intent i = getIntent();
final String month = Objects.requireNonNull(i.getExtras()).getString("Month");
//-------------------------------
btnBudget.setOnClickListener(v -> {
Intent o;
o = new Intent(MainActivity.this, AddBudgetActivity.class);
o.putExtra("Month",month);
startActivity(o);
finish();
});
if (type.equals("Income")) {
try {
totalEarned = (totalEarned+sum);
} catch (NumberFormatException ex) {
}
tvTotalIncome.setText("-)"+String.valueOf( totalEarned));
holder.btnIcon.setBackgroundResource(R.drawable.circlegreen);
holder.tvEntry.setText("(+)"+String.valueOf(sum) );
try {
totalSaved = (totalEarned-totalSpent);
} catch (NumberFormatException ex) {
}
tvTotalSaved.setText("(=)"+String.valueOf( totalSaved));
}else if (type.equals("Expanse")) {
try {
totalSpent = (totalSpent+sum);
} catch (NumberFormatException ex) {
}
tvTotalExpanse.setText("-)"+String.valueOf( totalSpent));
holder.btnIcon.setBackgroundResource(R.drawable.circlered);
holder.tvEntry.setText("(-)"+String.valueOf(sum) );
try {
totalSaved = (totalEarned-totalSpent);
} catch (NumberFormatException ex) {
}
tvTotalSaved.setText("(=)"+String.valueOf( totalSaved));
}else {
Toast.makeText(MainActivity.this, " Something Went Wrong !", Toast.LENGTH_SHORT).show();
}
//======================
myRef = myfire.getReference().child("Data").child(strUID).child(month);
//-------------------------
options = new FirebaseRecyclerOptions.Builder<entry>()
.setQuery(myRef, entry.class)
.build();
final FirebaseRecyclerAdapter<entry, holder_menu> adapter = new FirebaseRecyclerAdapter<entry, holder_menu>(options) {
#Override
protected void onBindViewHolder(#NonNull #NotNull holder_menu holder, final int i, #NonNull #NotNull entry model) {
final String title = getRef(i).getKey();
assert title != null;
myRef = myfire.getReference().child("Data").child(strUID).child(month).child(title).child("Budget");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
int budget = 0;
if (dataSnapshot.getValue() == null) {
Toast.makeText(getApplicationContext(), "Data Not Available", Toast.LENGTH_LONG).show();
} else {
final String stData1 = (Objects.requireNonNull(dataSnapshot.child("stData1").getValue())).toString();
final String stData2 = (Objects.requireNonNull(dataSnapshot.child("stData2").getValue())).toString();
final String stData3 = (Objects.requireNonNull(dataSnapshot.child("stData3").getValue())).toString();
final String stData4 = (Objects.requireNonNull(dataSnapshot.child("stData4").getValue())).toString();
entry basic = new entry(stData1, stData2, stData3, stData4);
String first = stData2.substring(0, 1);
holder.btnIcon.setText(first);
holder.tvHead.setText(stData2);
String type;
type=(stData3);
holder.tvBudget.setText("#" + stData4);
int amount = 0;
//important line
try {
amount = (Integer.parseInt(stData4));
} catch (NumberFormatException ex) {
}
//======================
budget = amount;
myRef = myfire.getReference().child("Data").child(strUID).child(month).child(title).child("Entry");
final int finalBudget = budget;
myRef.addValueEventListener(new ValueEventListener() {
int sum = 0;
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
String section = data.child("stData2").getValue(String.class);
String value = data.child("stData4").getValue(String.class);
assert value != null;
int total = 0;
//important line
try {
total = (Integer.parseInt(value));
} catch (NumberFormatException ex) {
}
//======================
sum = sum + total;
//==============
//======================
if (section.equals("Saving")) {
holder.tvHead.setBackgroundColor(getResources().getColor(R.color.saving));
}else if (section.equals("Paying")) {
holder.tvHead.setBackgroundColor(getResources().getColor(R.color.paying));
}else if (section.equals("Using")) {
holder.tvHead.setBackgroundColor(getResources().getColor(R.color.using));
}else if (section.equals("Earning")) {
holder.tvHead.setBackgroundColor(getResources().getColor(R.color.earning));
}else if (section.equals("Taking")) {
holder.tvHead.setBackgroundColor(getResources().getColor(R.color.taking));
}else if (section.equals("Drawing")) {
holder.tvHead.setBackgroundColor(getResources().getColor(R.color.drawing));
}else {
Toast.makeText(MainActivity.this, " Something Went Wrong !", Toast.LENGTH_SHORT).show();
}
}
holder.tvEntry.setText("(+)" + String.valueOf(sum) );
holder.tvBalance.setText("(=)" + String.valueOf(finalBudget - sum) );
//important line
holder.btnView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent o;
o = new Intent(MainActivity.this, ViewHistoryActivity.class);
o.putExtra("Title", title);
o.putExtra("Month", month);
o.putExtra("Type", type);
startActivity(o);
finish();
}
});
holder.btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (type.equals("Income")) {
Intent o;
o = new Intent(MainActivity.this, EntryIncomeActivity.class);
o.putExtra("Title", title);
o.putExtra("Month", month);
o.putExtra("Type", type);
startActivity(o);
finish();
}else if (type.equals("Expanse")) {
Intent o;
o = new Intent(MainActivity.this, EntryExpanseActivity.class);
o.putExtra("Title", title);
o.putExtra("Month", month);
o.putExtra("Type", type);
startActivity(o);
finish();
}else {
Toast.makeText(MainActivity.this, " Something Went Wrong !", Toast.LENGTH_SHORT).show();
}
}
});
if (type.equals("Income")) {
try {
totalEarned = (totalEarned+sum);
} catch (NumberFormatException ex) {
}
tvTotalIncome.setText("-)"+String.valueOf( totalEarned));
holder.btnIcon.setBackgroundResource(R.drawable.circlegreen);
holder.tvEntry.setText("(+)"+String.valueOf(sum) );
try {
totalSaved = (totalEarned-totalSpent);
} catch (NumberFormatException ex) {
}
tvTotalSaved.setText("(=)"+String.valueOf( totalSaved));
}else if (type.equals("Expanse")) {
try {
totalSpent = (totalSpent+sum);
} catch (NumberFormatException ex) {
}
tvTotalExpanse.setText("-)"+String.valueOf( totalSpent));
holder.btnIcon.setBackgroundResource(R.drawable.circlered);
holder.tvEntry.setText("(-)"+String.valueOf(sum) );
try {
totalSaved = (totalEarned-totalSpent);
} catch (NumberFormatException ex) {
}
tvTotalSaved.setText("(=)"+String.valueOf( totalSaved));
}else {
Toast.makeText(MainActivity.this, " Something Went Wrong !", Toast.LENGTH_SHORT).show();
}
//======================
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // never ignore errors
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // never ignore errors
}
});
}
#NonNull
#Override
public holder_menu onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item1, parent, false);
return new holder_menu(v);
}
};
adapter.startListening();
userlist.setAdapter(adapter);
}
}
EDITED QUESTION As per #androidLearner 's suggestion
MAIN ACTIVITY
public class MainActivity extends AppCompatActivity {
FirebaseDatabase myfire;
DatabaseReference myRef;
int totalEarned = 0;
int totalSpent = 0;
int totalSaved=0;
madapter adapter;
String iconsData;
String headsData;
int budgetsData=0;
int enteriesData=0;
int balancesData=0;
#Override
public void onBackPressed() {
final AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("Are you sure to exit?");
dialog.setPositiveButton("Play", (dialog1, which) -> {
});
dialog.setNegativeButton("Exit", (dialog12, which) -> {
FirebaseAuth.getInstance().signOut();
MainActivity.this.finish();
});
dialog.show();
}
private String getUID() {
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
if (mUser != null) {
String strUID = mUser.getUid();
if (!TextUtils.isEmpty(strUID)) {
return strUID;
}
}
return "";
}
#RequiresApi(api = Build.VERSION_CODES.N)
#SuppressLint("SetTextI18n")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//==============
final RecyclerView userlist = (RecyclerView) findViewById(R.id.idRecycleView);
myfire = FirebaseDatabase.getInstance();
userlist.setLayoutManager(new LinearLayoutManager(this));
//==================
final TextView tvTotalIncome = findViewById(R.id.idTotalIncome);
final TextView tvTotalExpanse = findViewById(R.id.idTotalExpanse);
final TextView tvTotalSaved = findViewById(R.id.idTotalSaved);
//==================
final FloatingActionButton btnBudget = findViewById(R.id.idCreateBudget);
myfire = FirebaseDatabase.getInstance();
final String strUID = getUID();
if (TextUtils.isEmpty(strUID)) {
//handle case of null UID
}
final Intent i = getIntent();
final String month = Objects.requireNonNull(i.getExtras()).getString("Month");
//-------------------------------
btnBudget.setOnClickListener(v -> {
Intent o;
o = new Intent(MainActivity.this, AddBudgetActivity.class);
o.putExtra("Month",month);
startActivity(o);
finish();
});
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&---new method
myRef = myfire.getReference().child("Data").child(strUID).child(month);
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
String title = dataSnapshot.getKey();
assert title != null;
myRef = myfire.getReference().child("Data").child(strUID).child(month).child(title).child("Budget");
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() == null) {
Toast.makeText(getApplicationContext(), "Data Not Available", Toast.LENGTH_LONG).show();
} else {
final String stData1 = (Objects.requireNonNull(dataSnapshot.child("stData1").getValue())).toString();
final String stData2 = (Objects.requireNonNull(dataSnapshot.child("stData2").getValue())).toString();
final String stData3 = (Objects.requireNonNull(dataSnapshot.child("stData3").getValue())).toString();
final String stData4 = (Objects.requireNonNull(dataSnapshot.child("stData4").getValue())).toString();
entry basic = new entry(stData1, stData2, stData3, stData4);
iconsData = stData2.substring(0, 1);
headsData=stData2;
//---------------------------------------------------------------------------entry
myRef = myfire.getReference().child("Data").child(strUID).child(month).child(title).child("Entry");
myRef.addValueEventListener(new ValueEventListener() {
int sum = 0;
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
String section = data.child("stData2").getValue(String.class);
String value = data.child("stData4").getValue(String.class);
assert value != null;
int total = 0;
try {
total=(Integer.parseInt(value));
} catch (NumberFormatException ex) {
}
//==============
sum=sum+total;
}
enteriesData=sum;
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // never ignore errors
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // never ignore errors
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // never ignore errors
}
});
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&------NewMethod
balancesData=budgetsData-enteriesData;
ArrayList<String> iconList = new ArrayList<>();
iconList.add(iconsData);
ArrayList<String> headList= new ArrayList<>();
headList.add(headsData);
ArrayList<Integer> budgetList = new ArrayList<>();
budgetList.add(budgetsData);
ArrayList<Integer> entryList = new ArrayList<>();
entryList.add(enteriesData);
ArrayList<Integer> balanceList = new ArrayList<>();
balanceList.add(balancesData);
adapter = new madapter ( this, iconList,headList,budgetList,entryList,balanceList);
userlist.setAdapter(adapter);
}
}
RECYCLER VIEW Adapter
public class madapter extends RecyclerView.Adapter<madapter.ViewHolder> {
private List<String> stricon;
private List<String> strhead;
private List<Integer> intbudget;
private List<Integer> intentry;
private List<Integer> intbalance;
//---
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
public madapter(MainActivity mainActivity, ArrayList<String> iconList, ArrayList<String> headList, ArrayList<Integer> budgetList, ArrayList<Integer> entryList, ArrayList<Integer> balanceList) {
this.mInflater = LayoutInflater.from(mainActivity);
this.stricon = iconList;
this.strhead = headList;
this.intbudget = budgetList;
this.intentry = entryList;
this.intbalance= balanceList;
}
// inflates the row layout from xml when needed
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.item1, parent, false);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String icons = stricon.get(position);
String heads = strhead.get(position);
int budgets = intbudget.get(position);
int entries = intentry.get(position);
int balances = intbalance.get(position);
holder.btnIcon.setText(icons);
holder.tvHead.setText(heads);
holder.tvBudget.setText(String.valueOf(budgets));
holder.tvEntry.setText(String.valueOf(entries));
holder.tvBalance.setText(String.valueOf(balances));
}
// total number of rows
#Override
public int getItemCount() {
return stricon.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public Button btnIcon;
public TextView tvHead;
public TextView tvBudget;
public TextView tvEntry;
public TextView tvBalance;
public Button btnView;
public Button btnAdd;
ViewHolder(View itemView) {
super(itemView);
btnIcon= (Button) itemView.findViewById(R.id.idIcon);
tvHead = (TextView) itemView.findViewById(R.id.idHead);
tvBudget = (TextView) itemView.findViewById(R.id.idBudget);
tvEntry = (TextView) itemView.findViewById(R.id.idEntry);
tvBalance = (TextView) itemView.findViewById(R.id.idBalance);
btnView= (Button) itemView.findViewById(R.id.idView);
btnAdd = (Button) itemView.findViewById(R.id.idAdd);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
String getItem(int id) {
return stricon.get(id);
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
THE NEW PROBLEM AFTER EDITING
I am not able to get any data from firebase to my array list by the method datasnapshot. But yes my recycler view shows data if I add hardcore text or numbers to my list manually.
This is the crash report
2021-05-24 00:07:12.368 19933-19933/com.myappname E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myappname, PID: 19933
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.get(ArrayList.java:437)
at com.myappname.model.rvAdapter.onBindViewHolder(mAdapter.java:54)
at com.myappname.model.rvAdapter.onBindViewHolder(mAdapter.java:16)2021-05-24 .......................................
set Adapter after got data from firebase
myRef.addValueEventListener(new ValueEventListener() {
int sum = 0;
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
String section = data.child("stData2").getValue(String.class);
String value = data.child("stData4").getValue(String.class);
assert value != null;
int total = 0;
//==============
sum=sum+total;
}
enteriesData=sum;
//Send your data to adapter as per your need from here
adapter = new madapter ( this, iconList,headList,budgetList,entryList,balanceList);
userlist.setAdapter(adapter);
}
I am trying to make android app for chatting when I send message done see it done but when I am trying to delete It nothing happens ... this is my adapter chat ... dialog message appear but when I am clicking on delete nothing happen ... when i am click on no dismiss dialog happen it is fine ... but nothing with delete ... any one can help me please ?
public class AdapterChat extends RecyclerView.Adapter<AdapterChat.MyHolder> {
private static final int MSG_TYPE_LEFT = 0;
private static final int MSG_TYPE_RIGHT = 1;
Context context;
List<Modelchat> chatList;
String imageUrl;
FirebaseUser fUser;
public AdapterChat(Context context, List<Modelchat> chatList, String imageUrl) {
this.context = context;
this.chatList = chatList;
this.imageUrl = imageUrl;
}
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
if (i == MSG_TYPE_RIGHT) {
View view = LayoutInflater.from(context).inflate(R.layout.row_chat_right, viewGroup, false);
return new MyHolder(view);
} else {
View view = LayoutInflater.from(context).inflate(R.layout.row_chat_left, viewGroup, false);
return new MyHolder(view);
}
}
#Override
public void onBindViewHolder(#NonNull MyHolder myHolder, final int i) {
String message = chatList.get(i).getMessage();
String timeStamp = chatList.get(i).getTimestamp();
Calendar cal = Calendar.getInstance(Locale.ENGLISH);
cal.setTimeInMillis(Long.parseLong(timeStamp));
String dataTime = DateFormat.format("dd/MM/yyyy hh:mm aa", cal).toString();
myHolder.messageTv.setText(message);
myHolder.timeTv.setText(dataTime);
try {
Picasso.get().load(imageUrl).into(myHolder.profileTv);
} catch (Exception e) {
}
//show delete dialog message
myHolder.messageLAyout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Delete");
builder.setMessage("Are you sure to delete this message?");
builder.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
deleteMessage(i);
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
});
if (i == chatList.size() - 1) {
if (chatList.get(i).isSeen()) {
myHolder.isSeenTv.setText("Seen");
} else {
myHolder.isSeenTv.setText("Delivered");
}
} else {
myHolder.isSeenTv.setVisibility(View.GONE);
}
}
private void deleteMessage(int position) {
String myUID = FirebaseAuth.getInstance().getCurrentUser().getUid();
String msgTimeStamp = chatList.get(position).getTimestamp();
DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference("Chats");
Query query = dbRef.orderByChild("timestamp").equalTo(msgTimeStamp);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
if (ds.child("sender").getValue().equals(myUID)) {
// ds.getRef().removeValue();
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("message", "This message was deleted...");
ds.getRef().updateChildren(hashMap);
chatList.remove(i);
notifyItemRemoved(i);
notifyItemRangeChanged(i, chatList.size());
Toast.makeText(context, "message deleted...", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "You can delete only your messages...", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#Override
public int getItemCount() {
return chatList.size();
}
#Override
public int getItemViewType(int position) {
fUser = FirebaseAuth.getInstance().getCurrentUser();
if (chatList.get(position).getSender().equals(fUser.getUid())) {
return MSG_TYPE_RIGHT;
} else {
return MSG_TYPE_LEFT;
}
}
class MyHolder extends RecyclerView.ViewHolder {
ImageView profileTv;
TextView messageTv, timeTv, isSeenTv;
LinearLayout messageLAyout;
public MyHolder(#NonNull View itemView) {
super(itemView);
profileTv = itemView.findViewById(R.id.profileTv);
messageTv = itemView.findViewById(R.id.messageTv);
timeTv = itemView.findViewById(R.id.timeTv);
isSeenTv = itemView.findViewById(R.id.isSeenTv);
messageLAyout = itemView.findViewById(R.id.messageLayout);
}
}
}
Emulator
I assume by delete you mean changing the text of the message to "This message was deleted...", if that is the case then the issue is that you update the database and don't update the object in the list:
Do this in deleteMessage(int position) function:
....
....
if (ds.child("sender").getValue().equals(myUID)) {
//ds.getRef().removeValue();
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("message", "This message was deleted...");
ds.getRef().updateChildren(hashMap);
Toast.makeText(context, "message deleted...", Toast.LENGTH_SHORT).show();
//here add these lines to update the list value.........
chatList.get(position).setMessage("This message was deleted...");
notifyDataSetChanged();
......
......
Just delete message success remove that position from list and notifyItemRemoved() try following code
if (ds.child("sender").getValue().equals(myUID)) {
// ds.getRef().removeValue();
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("message", "This message was deleted...");
ds.getRef().updateChildren(hashMap);
chatList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, chatList.size());
Toast.makeText(context, "message deleted...", Toast.LENGTH_SHORT).show();
}
Hi I have switch button (switchTaskFinished) on my recycler view,when I am clicking any button, the last button is getting selected. Also when I press button it updates the data to firebase. And changes the button status accordingly. But even though buttons value is true it only updates last button status not others.
public class MyAdaptorUser extends RecyclerView.Adapter<MyAdaptorUser.myViewHolder> {
private Context context;
private ArrayList<TaskModel> taskLists;
private Switch switchTaskFinished;
private OnTaskClickListner mTaskListner;
private AlertDialog dialog;
private AlertDialog.Builder builder;
private TaskConfirmationSender taskConfirmationSender;
public MyAdaptorUser(Context c, ArrayList<TaskModel> t, OnTaskClickListner onTaskClickListner) {
context = c;
taskLists = t;
this.mTaskListner = onTaskClickListner;
}
#NonNull
#Override
public MyAdaptorUser.myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
builder = new AlertDialog.Builder(parent.getContext());
builder.setTitle("Please Wait").setView(R.layout.my_progress_view).setCancelable(false);
dialog = builder.create();
return new MyAdaptorUser.myViewHolder(LayoutInflater.from(context).inflate(R.layout.task_preview, parent, false), mTaskListner);
}
#Override
public void onBindViewHolder(#NonNull MyAdaptorUser.myViewHolder holder, final int position) {
//Set title and description to task preview textviews
holder.title.setText(taskLists.get(position).getTaskTitle());
holder.dueDate.setText(taskLists.get(position).getDueDate());
holder.description.setText(taskLists.get(position).getTaskDescription());
//Sets the path of database to taskAwatingConfirmation/task_title/UserEmail
final DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference();
try {
String email = FirebaseAuth.getInstance().getCurrentUser().getEmail();
email = removeSpecialCharacter(email);
final DatabaseReference taskConfirmationRef = dbRef
.child("taskAwatingConfirmation")
.child(taskLists.get(position).getTaskTitle())
.child(email);
taskConfirmationRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
//Fetching switchButton Status (Task finished) from database
switchTaskFinished.setChecked(false);
String buttonStatus = (String) dataSnapshot.child("buttonStatus").getValue();
if (buttonStatus != null) {
Log.d("taskerror", buttonStatus);
if (buttonStatus.equals("true")) {
switchTaskFinished.setChecked(true);
} else if (buttonStatus.equals("false")) {
switchTaskFinished.setChecked(false);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
switchTaskFinished.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(final CompoundButton buttonView, boolean isChecked) {
//dialog = builder.show();
taskConfirmationSender = new TaskConfirmationSender();
//When Task Finished button is clicked send data to database
sendConfirmationToAdmin(new FirebaseCallBack() {
#Override
public void Callback(TaskConfirmationSender taskConfirmationSender) {
taskConfirmationSender.setButtonStatus(String.valueOf(buttonView.isChecked()));
taskConfirmationSender.setTaskDueDate(taskLists.get(position).getDueDate());
if (buttonView.isChecked()) {
taskConfirmationRef.setValue(taskConfirmationSender).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
dialog.dismiss();
}
});
}else{
taskConfirmationRef.setValue(taskConfirmationSender).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
dialog.dismiss();
}
});
}
}
});
}
});
} catch (NullPointerException ignored) {
dialog.dismiss();
}
}
private String removeSpecialCharacter(String email) {
StringBuffer sbf = new StringBuffer(email);
email = String.valueOf(sbf.reverse());
int length = email.length();
email = email.substring(4, length);
StringBuffer stringBuffer = new StringBuffer(email);
email = String.valueOf(stringBuffer.reverse());
return email.replace("#", "_");
}
private void sendConfirmationToAdmin(final FirebaseCallBack firebaseCallBack) {
DatabaseReference volunteerRef = FirebaseDatabase.getInstance().getReference()
.child("Volunteer").child("Member")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
taskConfirmationSender = new TaskConfirmationSender();
try {
//Fetching details of users (full name, email) from database and setting their value to taskConfirmation Object
volunteerRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String userName = dataSnapshot.child("fullName").getValue().toString();
String userEmail = dataSnapshot.child("email").getValue().toString();
String userId = dataSnapshot.getKey();
//TODO: Fetch UID of user and set it to taskConfirmation OBject
taskConfirmationSender.setUserEmail(userEmail);
taskConfirmationSender.setUserName(userName);
taskConfirmationSender.setId(userId);
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1;
int day = calendar.get(Calendar.DAY_OF_MONTH);
String submissionDate = day + "/" + month + "/" + year;
taskConfirmationSender.setSubmissionDate(submissionDate);
firebaseCallBack.Callback(taskConfirmationSender);
/**/
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
} catch (NullPointerException ee) {
}
}
private interface FirebaseCallBack {
void Callback(TaskConfirmationSender taskConfirmationSender);
}
#Override
public int getItemCount() {
return taskLists.size();
}
class myViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView title, dueDate, description;
OnTaskClickListner onTaskClickListner;
public myViewHolder(#NonNull View itemView, OnTaskClickListner onTaskClickListner) {
super(itemView);
title = itemView.findViewById(R.id.taskTitle);
dueDate = itemView.findViewById(R.id.taskDueDate);
description = itemView.findViewById(R.id.taskDescription);
switchTaskFinished = itemView.findViewById(R.id.switchTaskFinished);
this.onTaskClickListner = onTaskClickListner;
ConstraintLayout taskBar = itemView.findViewById(R.id.linearLayoutTaskBar);
itemView.setOnClickListener(this);
//hides delete task button
taskBar.setVisibility(View.GONE);
}
#Override
public void onClick(View v) {
onTaskClickListner.onTaskClick(getAdapterPosition());
}
}
public interface OnTaskClickListner {
void onTaskClick(int position);
}
}
Maybe its because of the valueEventListener that stays attached:
Instead of this:
taskConfirmationRef.addValueEventListener(new ValueEventListener() {.........
Do this:
taskConfirmationRef.addListenerForSingleValueEvent(new ValueEventListener() {......
And set the switch to checked or unchecked when you turn on or off:
if (buttonView.isChecked()) {
//here
switchTaskFinished.setChecked(true);
taskConfirmationRef.setValue(taskConfirmationSender).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
dialog.dismiss();
}
});
}else{
//here
switchTaskFinished.setChecked(false);
...................
I'm loading json file from online and saving it on Sqlite such that when app is offline...Then still user will be able to see the data.
It works fine in MainActivity.
But when I try to covert it into fragment, I'm getting errors of Fragment cannot be cast in to FlowerAdapter$FlowerClickListener
Here is the error file
My Fragment name is nepali.
Here is the Mainactivity
public class MainActivity extends AppCompatActivity implements FlowerAdapter.FlowerClickListener, FlowerFetchListener {
private static final String TAG = MainActivity.class.getSimpleName();
private RecyclerView mRecyclerView;
private RestManager mManager;
private FlowerAdapter mFlowerAdapter;
private FlowerDatabase mDatabase;
private Button mReload;
private ProgressDialog mDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
configViews();
mManager = new RestManager();
mDatabase = new FlowerDatabase(this);
loadFlowerFeed();
mReload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loadFlowerFeed();
}
});
}
private void loadFlowerFeed() {
mDialog = new ProgressDialog(MainActivity.this);
mDialog.setMessage("Loading Flower Data...");
mDialog.setCancelable(true);
mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mDialog.setIndeterminate(true);
mFlowerAdapter.reset();
mDialog.show();
if (getNetworkAvailability()) {
getFeed();
} else {
getFeedFromDatabase();
}
}
private void getFeedFromDatabase() {
mDatabase.fetchFlowers(this);
}
private void configViews() {
mReload = (Button) findViewById(R.id.reload);
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setRecycledViewPool(new RecyclerView.RecycledViewPool());
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));
mFlowerAdapter = new FlowerAdapter(this);
mRecyclerView.setAdapter(mFlowerAdapter);
}
#Override
public void onClick(int position) {
}
public void getFeed() {
Call<List<Flower>> listCall = mManager.getFlowerService().getAllFlowers();
listCall.enqueue(new Callback<List<Flower>>() {
#Override
public void onResponse(Call<List<Flower>> call, Response<List<Flower>> response) {
if (response.isSuccessful()) {
List<Flower> flowerList = response.body();
for (int i = 0; i < flowerList.size(); i++) {
Flower flower = flowerList.get(i);
SaveIntoDatabase task = new SaveIntoDatabase();
task.execute(flower);
mFlowerAdapter.addFlower(flower);
}
} else {
int sc = response.code();
switch (sc) {
case 400:
Log.e("Error 400", "Bad Request");
break;
case 404:
Log.e("Error 404", "Not Found");
break;
default:
Log.e("Error", "Generic Error");
}
}
mDialog.dismiss();
}
#Override
public void onFailure(Call<List<Flower>> call, Throwable t) {
mDialog.dismiss();
Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
public boolean getNetworkAvailability() {
return Utils.isNetworkAvailable(getApplicationContext());
}
#Override
public void onDeliverAllFlowers(List<Flower> flowers) {
}
#Override
public void onDeliverFlower(Flower flower) {
mFlowerAdapter.addFlower(flower);
}
#Override
public void onHideDialog() {
mDialog.dismiss();
}
public class SaveIntoDatabase extends AsyncTask<Flower, Void, Void> {
private final String TAG = SaveIntoDatabase.class.getSimpleName();
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Flower... params) {
Flower flower = params[0];
try {
} catch (Exception e) {
Log.d(TAG, e.getMessage());
}
return null;
}
}
}
and FlowerDatabase class is
public class FlowerDatabase extends SQLiteOpenHelper {
private static final String TAG = FlowerDatabase.class.getSimpleName();
public FlowerDatabase(Context context) {
super(context, Constants.DATABASE.DB_NAME, null, Constants.DATABASE.DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(Constants.DATABASE.CREATE_TABLE_QUERY);
} catch (SQLException ex) {
Log.d(TAG, ex.getMessage());
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(Constants.DATABASE.DROP_QUERY);
this.onCreate(db);
}
public void addFlower(Flower flower) {
Log.d(TAG, "Values Got " + flower.getName());
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(Constants.DATABASE.PRODUCT_ID, flower.getProductId());
values.put(Constants.DATABASE.CATEGORY, flower.getCategory());
values.put(Constants.DATABASE.PRICE, Double.toString(flower.getPrice()));
values.put(Constants.DATABASE.INSTRUCTIONS, flower.getInstructions());
values.put(Constants.DATABASE.NAME, flower.getName());
try {
db.insert(Constants.DATABASE.TABLE_NAME, null, values);
} catch (Exception e) {
}
db.close();
}
public void fetchFlowers(FlowerFetchListener listener) {
FlowerFetcher fetcher = new FlowerFetcher(listener, this.getWritableDatabase());
fetcher.start();
}
public class FlowerFetcher extends Thread {
private final FlowerFetchListener mListener;
private final SQLiteDatabase mDb;
public FlowerFetcher(FlowerFetchListener listener, SQLiteDatabase db) {
mListener = listener;
mDb = db;
}
#Override
public void run() {
Cursor cursor = mDb.rawQuery(Constants.DATABASE.GET_FLOWERS_QUERY, null);
final List<Flower> flowerList = new ArrayList<>();
if (cursor.getCount() > 0) {
if (cursor.moveToFirst()) {
do {
Flower flower = new Flower();
flower.setFromDatabase(true);
flower.setName(cursor.getString(cursor.getColumnIndex(Constants.DATABASE.NAME)));
flower.setPrice(Double.parseDouble(cursor.getString(cursor.getColumnIndex(Constants.DATABASE.PRICE))));
flower.setInstructions(cursor.getString(cursor.getColumnIndex(Constants.DATABASE.INSTRUCTIONS)));
flower.setCategory(cursor.getString(cursor.getColumnIndex(Constants.DATABASE.CATEGORY)));
flower.setProductId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(Constants.DATABASE.PRODUCT_ID))));
flowerList.add(flower);
publishFlower(flower);
} while (cursor.moveToNext());
}
}
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
mListener.onDeliverAllFlowers(flowerList);
mListener.onHideDialog();
}
});
}
public void publishFlower(final Flower flower) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
mListener.onDeliverFlower(flower);
}
});
}
}
}
and FlowerAdapter Class is
public class FlowerAdapter extends RecyclerView.Adapter<FlowerAdapter.Holder> {
private static final String TAG = FlowerAdapter.class.getSimpleName();
private final FlowerClickListener mListener;
private List<Flower> mFlowers;
public FlowerAdapter(FlowerClickListener listener) {
mFlowers = new ArrayList<>();
mListener = listener;
}
#Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View row = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item, null, false);
return new Holder(row);
}
#Override
public void onBindViewHolder(Holder holder, int position) {
Flower currFlower = mFlowers.get(position);
holder.mName.setText(currFlower.getName());
holder.minstruction.setText(currFlower.getInstructions());
}
#Override
public int getItemCount() {
return mFlowers.size();
}
public void addFlower(Flower flower) {
mFlowers.add(flower);
notifyDataSetChanged();
}
/**
* #param position
* #return
*/
public Flower getSelectedFlower(int position) {
return mFlowers.get(position);
}
public void reset() {
mFlowers.clear();
notifyDataSetChanged();
}
public class Holder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView mName, minstruction;
public Holder(View itemView) {
super(itemView);
mName = (TextView) itemView.findViewById(R.id.flowerName);
minstruction = (TextView) itemView.findViewById(R.id.flowerPrice);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
mListener.onClick(getLayoutPosition());
}
}
public interface FlowerClickListener {
void onClick(int position);
}
}
My fragment class is that I try to convert above Mainactivity code into Frament class is
public class nepali extends Fragment {
private static final String TAG = nepali.class.getSimpleName();
private RecyclerView mRecyclerView;
private RestManager mManager;
private FlowerAdapter mFlowerAdapter;
private FlowerDatabase mDatabase;
private Button mReload;
private ProgressDialog mDialog;
View view;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.activity_data, container, false);
configViews();
mManager = new RestManager();
mDatabase = new FlowerDatabase(getActivity());
loadFlowerFeed();
mReload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loadFlowerFeed();
}
});
return view;
}
private void loadFlowerFeed() {
mDialog = new ProgressDialog(getActivity());
mDialog.setMessage("Loading Flower Data...");
mDialog.setCancelable(true);
mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mDialog.setIndeterminate(true);
mFlowerAdapter.reset();
mDialog.show();
if (getNetworkAvailability()) {
getFeed();
} else {
getFeedFromDatabase();
}
}
private void getFeedFromDatabase() {
mDatabase.fetchFlowers(this);
}
private void configViews() {
mReload = (Button) view.findViewById(R.id.reload);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setRecycledViewPool(new RecyclerView.RecycledViewPool());
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
mFlowerAdapter = new FlowerAdapter((FlowerAdapter.FlowerClickListener) this);;
mRecyclerView.setAdapter(mFlowerAdapter);
}
public void getFeed() {
Call<List<Flower>> listCall = mManager.getFlowerService().getAllFlowers();
listCall.enqueue(new Callback<List<Flower>>() {
#Override
public void onResponse(Call<List<Flower>> call, Response<List<Flower>> response) {
if (response.isSuccessful()) {
List<Flower> flowerList = response.body();
for (int i = 0; i < flowerList.size(); i++) {
Flower flower = flowerList.get(i);
SaveIntoDatabase task = new SaveIntoDatabase();
task.execute(flower);
mFlowerAdapter.addFlower(flower);
}
} else {
int sc = response.code();
switch (sc) {
case 400:
Log.e("Error 400", "Bad Request");
break;
case 404:
Log.e("Error 404", "Not Found");
break;
default:
Log.e("Error", "Generic Error");
}
}
mDialog.dismiss();
}
#Override
public void onFailure(Call<List<Flower>> call, Throwable t) {
mDialog.dismiss();
Toast.makeText(getActivity(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
public boolean getNetworkAvailability() {
return Utils.isNetworkAvailable(getActivity());
}
public void onDeliverFlower(Flower flower) {
mFlowerAdapter.addFlower(flower);
}
public void onHideDialog() {
mDialog.dismiss();
}
public class SaveIntoDatabase extends AsyncTask<Flower, Void, Void> {
private final String TAG = SaveIntoDatabase.class.getSimpleName();
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Flower... params) {
Flower flower = params[0];
try {
} catch (Exception e) {
Log.d(TAG, e.getMessage());
}
return null;
}
}
}
Lastly the FlowerService class is
public interface FlowerService {
#GET("/routine/first.json")
Call<List<Flower>> getAllFlowers();
}
and FlowerFetchListener Class is
public interface FlowerFetchListener {
void onDeliverAllFlowers(List<Flower> flowers);
void onDeliverFlower(Flower flower);
void onHideDialog();
}
Please Help....and Thanks in advance.
You should not call db and network from activity or fragment. Try to learn MVVM architecture and use ViewModel to store the data from db or network. You may put a lot of effort making your app work but it will still lead to crashes (especially after you introduce fragment and call db and API from there). You will need to handle your data state during configuration changes. Listen to this talk and start writing clean code https://m.youtube.com/watch?v=5qlIPTDE274
The error you get is because you pass wrong parameter into adapter constructor ‘new FlowerAdapter((FlowerAdapter.FlowerClickListener) this)’. If you want to pass a listener to the adapter you need to pass the class which implements the listener: either activity - then pass getActivity(), or fragment ‘this’ - then make fragment implement implements FlowerAdapter.FlowerClickListener.Be aware that it can be null when fragment is not attached to activity, eg configuration change.