Could you please assist in following issue:
I have incorrect displaying items in my messenger app.
My layout for items:
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
app:cardElevation="0dp">
<TextView
android:id="#+id/message_my_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:gravity="end"
android:textColor="#color/black"
android:textSize="14sp"
android:visibility="invisible"
/>
<TextView
android:id="#+id/message_your_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:gravity="start"
android:textColor="#color/black"
android:textSize="14sp"
android:visibility="invisible"
/>
</com.google.android.material.card.MaterialCardView>
My layout for dialog activity:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DialogActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/dialog_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/Theme.AnonymousAd.AppBarOverlay">
<include
android:id="#+id/dialog_app_bar"
layout="#layout/app_bar_layout"
>
</include>
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/dialog_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:clickable="true"
android:contentDescription="TODO"
android:focusable="true"
android:src="#drawable/ic_send"
android:visibility="invisible"
app:fabSize="mini"
tools:ignore="SpeakableTextPresentCheck" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/dialog_attach"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:clickable="true"
android:contentDescription="TODO"
android:focusable="true"
android:src="#drawable/ic_attach"
app:fabSize="mini"
tools:ignore="SpeakableTextPresentCheck" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/dialog_gift"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:clickable="true"
android:contentDescription="TODO"
android:focusable="true"
android:src="#drawable/ic_gift"
app:fabSize="mini"
tools:ignore="SpeakableTextPresentCheck" />
<EditText
android:id="#+id/dialog_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="#+id/dialog_send"
android:layout_toRightOf="#+id/dialog_gift"
android:autofillHints=""
android:backgroundTint="#color/teal_700"
android:hint="#string/dialog_enter_message"
android:inputType="textCapSentences|textMultiLine"
android:maxHeight="120dp"
android:maxLength="500"
android:minHeight="48dp"
android:textColorHint="#757575"
android:textSize="16sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/dialog_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/dialog_message"
android:layout_below="#+id/dialog_appbar"
android:layout_marginBottom="5dp"
android:focusedByDefault="true"
android:scrollbars="vertical" />
Class DialogActivity
public class DialogActivity extends AppCompatActivity {
private RecyclerView dialogRecyclerView;
private LinearLayoutManager layoutManager;
private final List<Message> messageList = new ArrayList<>();
private MessageAdapter messageAdapter;
private String idText;
private String userNameText;
private EditText dialogMessage;
private Toolbar toolbar;
private FloatingActionButton dialogSend;
private FloatingActionButton dialogAttach;
private String downloadedImageUrl;
private StorageTask uploadTask;
private Uri imageUri;
private DatabaseReference dialogsDataBase;
private ProgressDialog loadingBar;
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference answersDataBase = db.collection("AnswersDataBase");
private StorageReference imageDataBase;
#SuppressLint("WrongViewCast")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialog);
idText = getIntent().getExtras().get("idText").toString();
userNameText = getIntent().getExtras().get("userNameText").toString();
dialogsDataBase = FirebaseDatabase.getInstance().getReference().child("DialogsDataBase").child(idText);
imageDataBase = FirebaseStorage.getInstance().getReference().child("imageDataBase");
toolbar = findViewById(R.id.dialog_app_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(userNameText);
messageAdapter = new MessageAdapter(this, messageList);
dialogRecyclerView = findViewById(R.id.dialog_recycler_view);
dialogRecyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
layoutManager.setStackFromEnd(true);
dialogRecyclerView.setLayoutManager(layoutManager);
dialogRecyclerView.setAdapter(messageAdapter);
loadingBar = new ProgressDialog(this);
dialogMessage = findViewById(R.id.dialog_message);
dialogAttach = findViewById(R.id.dialog_attach);
dialogAttach.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
//startActivityForResult(intent, 438);
someActivityResultLauncher.launch(intent);
}
});
dialogMessage.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if(dialogMessage.getText().toString().length() > 0){
dialogAttach.setVisibility(View.INVISIBLE);
dialogSend.setVisibility(View.VISIBLE);
}
else {
dialogAttach.setVisibility(View.VISIBLE);
dialogSend.setVisibility(View.INVISIBLE);
}
}
#Override
public void afterTextChanged(Editable editable) {
}
});
dialogSend = findViewById(R.id.dialog_send);
dialogSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(dialogMessage.getText().toString().length() > 0){
answersDataBase.document(idText).update("answer", dialogMessage.getText().toString());
dialogsDataBase.push().setValue(new Message(Paper.book().read("userName"), dialogMessage.getText().toString(), "text"));
dialogMessage.setText("");
}
}
});
}
#Override
protected void onStart() {
super.onStart();
dialogsDataBase.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot snapshot, #Nullable String previousChildName) {
Message message = snapshot.getValue(Message.class);
messageList.add(message);
messageAdapter.notifyDataSetChanged();
dialogRecyclerView.smoothScrollToPosition(dialogRecyclerView.getAdapter().getItemCount());
}
#Override
public void onChildChanged(#NonNull DataSnapshot snapshot, #Nullable String previousChildName) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot snapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot snapshot, #Nullable String previousChildName) {
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
ActivityResultLauncher<Intent> someActivityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
#Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
loadingBar.setTitle("Sending Image");
loadingBar.setMessage("Please wait, we are sending that image");
loadingBar.setCanceledOnTouchOutside(false);
loadingBar.show();
// There are no request codes
Intent data = result.getData();
imageUri = data.getData();
StorageReference filePath = imageDataBase.child(System.currentTimeMillis() + ".jpg");
uploadTask = filePath.putFile(imageUri);
uploadTask.continueWithTask(new Continuation() {
#Override
public Object then(#NonNull Task task) throws Exception {
if(!task.isSuccessful()){
throw task.getException();
}
return filePath.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if(task.isSuccessful()){
Uri downloadUrl = task.getResult();
downloadedImageUrl = downloadUrl.toString();
answersDataBase.document(idText).update("answer", "Photo");
dialogsDataBase.push().setValue(new Message(Paper.book().read("userName"), downloadedImageUrl, "image"));
loadingBar.dismiss();
recreate();
}
}
});
}
}
});
#Override
protected void onDestroy() {
super.onDestroy();
messageList.clear();
}
#Override
protected void onPause() {
super.onPause();
messageList.clear();
}
}
Adapter class
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MessageViewHolderNew> {
private Context context;
private List<Message> messagesList;
private Dialog dialog;
private String userNameString;
public MessageAdapter(Context context, List<Message> messagesList){
this.context = context;
this.messagesList = messagesList;
userNameString = Paper.book().read("userName");
}
public class MessageViewHolderNew extends RecyclerView.ViewHolder{
private TextView messageMyMessage;
private TextView messageYourMessage;
private ImageView messageMyImage;
private ImageView messageYourImage;
public MessageViewHolderNew(#NonNull View itemView) {
super(itemView);
messageMyMessage = (TextView) itemView.findViewById(R.id.message_my_message);
messageYourMessage = (TextView) itemView.findViewById(R.id.message_your_message);
messageMyImage = (ImageView) itemView.findViewById(R.id.message_my_image);
messageYourImage = (ImageView) itemView.findViewById(R.id.message_your_image);
}
}
#NonNull
#Override
public MessageViewHolderNew onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.message_items_layout, parent, false);
return new MessageViewHolderNew(view);
}
#Override
public void onBindViewHolder(#NonNull MessageViewHolderNew holder, int position) {
if(messagesList.get(position).getUserName().equals(userNameString)){
holder.messageMyMessage.setText(messagesList.get(position).getMessage());
holder.messageMyMessage.setVisibility(View.VISIBLE);
}
else{
holder.messageYourMessage.setText(messagesList.get(position).getMessage());
holder.messageYourMessage.setVisibility(View.VISIBLE);
}
}
#Override
public int getItemCount() {
return messagesList.size();
}
}
In this place I check user name.
if(messagesList.get(position).getUserName().equals(userNameString)){
holder.messageMyMessage.setText(messagesList.get(position).getMessage());
holder.messageMyMessage.setVisibility(View.VISIBLE);
}
else{
holder.messageYourMessage.setText(messagesList.get(position).getMessage());
holder.messageYourMessage.setVisibility(View.VISIBLE);
}
If user name is my name then I set message and visible to holder.messageMyMessage.
Else I set message and visible to holder.messageYourMessage.
But sometimes message and visible are set to both messages while scrolling or sent new message. .
See attached screenshot for details
Your problem's here:
if(messagesList.get(position).getUserName().equals(userNameString)){
holder.messageMyMessage.setText(messagesList.get(position).getMessage());
holder.messageMyMessage.setVisibility(View.VISIBLE);
} else {
holder.messageYourMessage.setText(messagesList.get(position).getMessage());
holder.messageYourMessage.setVisibility(View.VISIBLE);
}
You're only making stuff visible, you're never hiding the other thing.
So if a specific ViewHolder is used to display one kind of message, it'll be made visible in onBindViewHolder. The view in that ViewHolder's layout will be set to VISIBLE.
Then, if you scroll down the list and the same ViewHolder is reused to display the other kind of message, the other message view in the layout will be set to VISIBLE. The other message view hasn't changed, it's still in the same state, VISIBLE. So you see them both (depending on how the layout works, one might be covering the other).
When you're using a RecyclerView, because the ViewHolders are reused (recycled) you need to set them up correctly for each item, clearing all the previous state. So in your case, for each message display, you have to either make it visible or hide it. You can't do nothing, because that can leave you with old state from the previous item it was displaying, right?
So you need to do this:
if(messagesList.get(position).getUserName().equals(userNameString)){
holder.messageMyMessage.setText(messagesList.get(position).getMessage());
holder.messageMyMessage.setVisibility(View.VISIBLE);
// now you need to make sure the other is -not- visible!
holder.messageYourMessage.setVisibility(View.GONE);
} else {
holder.messageYourMessage.setText(messagesList.get(position).getMessage());
holder.messageYourMessage.setVisibility(View.VISIBLE);
// same thing - explicitly hide the other one, assume it could be visible
holder.messageMyMessage.setVisibility(View.GONE);
}
This is the number one thing you need to do with a RecyclerView - in onBindViewHolder, always set up everything that can change depending on the item. Assume it has old data or the wrong thing set, and explicitly initialise everything. It's like a whiteboard - when you start using it you need to clean it, because maybe there's some old stuff on there
Related
This question already has an answer here:
Firestore whereEqualTo, orderBy and limit(1) not working
(1 answer)
Closed 1 year ago.
I'm able to add a message to firestore when I clicked the send button in the chatroom, but the recyclerview doesn't update in realtime so the new message doesn't appear. The message does appear when I reopen the chatroom which isn't best pratice. Normally FirestoreRecyclerAdapter should automatically updated the query when changes are made and update the recyclerview.
I'm working in Android Studio with Java and using fragments instead of activities.
ChatRoomFragment:
public class ChatRoomFragment extends Fragment {
private static final String TAG = "Notable:ChatRoom";
private FirebaseFirestore db;
private Query query;
private FirestoreRecyclerAdapter<Message, MessageAdapter.MessageHolder> adapter;
private FirebaseAuth mAuth;
private FirebaseUser currentUser;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.chatroom_fragment, container, false);
MaterialToolbar topBar = view.findViewById(R.id.topAppBar);
Button sendButton = view.findViewById(R.id.send_message);
EditText input = view.findViewById(R.id.message_edit_text);
RecyclerView chatRecyclerView = view.findViewById(R.id.chat_recyclerview);
mAuth = FirebaseAuth.getInstance();
currentUser = mAuth.getCurrentUser();
db = FirebaseFirestore.getInstance();
//FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder().setPersistenceEnabled(true).setCacheSizeBytes(FirebaseFirestoreSettings.CACHE_SIZE_UNLIMITED).build();
//db.setFirestoreSettings(settings);
String key = mAuth.getCurrentUser().getUid();
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
layoutManager.setStackFromEnd(true);
chatRecyclerView.setLayoutManager(layoutManager);
String title = this.getArguments().getString("buttonText");
topBar.setTitle(title);
query = db.collection("messages").whereEqualTo("chatGroup", title).orderBy("messageTime");
adapter = new MessageAdapter(getActivity(), query, key);
//https://medium.com/#akhilkc9/simple-android-chat-application-using-firestorerecycleradapter-7f632da2eaee
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeChanged(int positionStart, int itemCount) {
super.onItemRangeChanged(positionStart, itemCount);
chatRecyclerView.scrollToPosition(itemCount);
}
});
chatRecyclerView.setAdapter(adapter);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String text = input.getText().toString();
if(!text.equals("")){
db.collection("users").document(key).get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists()){
String firstName = documentSnapshot.get("firstname").toString();
db.collection("messages").add(new Message(firstName, text, key, title));
}else{
Log.w(TAG, "No such document");
}
}
});
}
input.setText("");
}
});
return view;
}
#Override
public void onStart() {
super.onStart();
if(adapter!=null) adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
if(adapter!=null) adapter.stopListening();
}
}
MessageAdapter:
public class MessageAdapter extends FirestoreRecyclerAdapter<Message, MessageAdapter.MessageHolder> {
private final String TAG = "MessageAdapter";
Context context;
String userId;
StorageReference storageReference;
private RequestOptions requestOptions = new RequestOptions();
private final int MESSAGE_IN_VIEW_TYPE = 1;
private final int MESSAGE_OUT_VIEW_TYPE = 2;
public MessageAdapter(#NonNull Context context, Query query, String userID) {
super(new FirestoreRecyclerOptions.Builder<Message>().setQuery(query, Message.class).build());
this.context = context;
this.userId = userID;
}
#Override
public int getItemViewType(int position) {
if(getItem(position).getMessageUserId().equals(userId)){
return MESSAGE_IN_VIEW_TYPE;
}
return MESSAGE_OUT_VIEW_TYPE;
}
#Override
public MessageHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = null;
if(viewType==MESSAGE_IN_VIEW_TYPE){
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_item, parent, false);
}else{
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.chat_item_other, parent, false);
}
return new MessageHolder(view);
}
//Voordeel van Recyclerview is dat het automatisch een Viewholder heeft, dit heeft gridview niet automatisch
#Override
protected void onBindViewHolder(#NonNull MessageHolder holder, int position, #NonNull Message model) {
final TextView mText = holder.mText;
final TextView mUsername = holder.mUsername;
final TextView mTime = holder.mTime;
final TextView mDate = holder.mDate;
final ImageView imgProfile = holder.imgProfile;
if(mUsername != null && imgProfile != null){
mUsername.setText(model.getMessageUser());
//Glide.with(context).setDefaultRequestOptions(requestOptions).load(R.drawable.placeholder).diskCacheStrategy(DiskCacheStrategy.DATA).into(imgProfile);
//storageReference.child(model.getMessageUserId())
}
mText.setText(model.getMessageText());
mDate.setText(DateFormat.format("dd MMM", model.getMessageTime()));
mTime.setText(DateFormat.format("h:mm", model.getMessageTime()));
}
static class MessageHolder extends RecyclerView.ViewHolder {
TextView mText;
TextView mUsername;
TextView mTime;
TextView mDate;
ImageView imgProfile;
public MessageHolder(View itemView) {
super(itemView);
mText = itemView.findViewById(R.id.message_text);
mUsername = itemView.findViewById(R.id.message_user);
mTime = itemView.findViewById(R.id.message_time);
mDate = itemView.findViewById(R.id.message_date);
imgProfile = itemView.findViewById(R.id.imgDps);
}
}
}
chatroom_fragment.xml :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/layout_group_chat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:orientation="vertical"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="#+id/topAppBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="#string/chat_group"
style="#style/Widget.MaterialComponents.Toolbar.Primary" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/chat_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="16dp"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toTopOf="#+id/text_indicator"
app:layout_constraintTop_toBottomOf="#+id/layout_group_chat" />
<TextView
android:id="#+id/text_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="#id/view"
app:layout_constraintStart_toStartOf="parent" />
<View
android:id="#+id/view"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#e0e0e0"
app:layout_constraintBottom_toTopOf="#+id/layout_chatbox" />
<RelativeLayout
android:id="#+id/layout_chatbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent">
<EditText
android:layout_marginStart="16dp"
android:id="#+id/message_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:background="#android:color/transparent"
android:hint="#string/hint_message"
android:inputType="text"
android:maxLines="6"
tools:ignore="Autofill" />
<Button
android:id="#+id/send_message"
android:layout_width="74dp"
android:layout_height="48dp"
android:layout_alignParentEnd="true"
android:background="?attr/selectableItemBackground"
android:text="#string/send"
android:textColor="#color/design_default_color_primary" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Fixed the problem, it was because I didn't add an index for the query on firestore.
I got a error from the android studio console (and firestore) that explained it see link:
https://coderedirect.com/questions/651254/firebase-firestore-query-error-9-failed-precondition-the-query-requires-an-i
I changed my activity to fragment for some reason but now my recycler view is not shown I have also checked the ArrayList that I want to show on recycler view it was not empty. The same code is working in another activity and fragments but not in this fragment. Please someone help me out!! Thank you in advance
my fragment code
public class HomeSkillsFragment extends Fragment {
private EditText Search;
private ImageView back;
private RecyclerView recyclerView;
private ArrayList<Post> postItem;
private postAdapter adapter;
private GridLayoutManager gridLayoutManager;
private DatabaseReference reference;
private BottomNavigationVisibility bottomNavigationVisibility;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home_skills, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
bottomNavigationVisibility = new BottomNavigationVisibility(getActivity());
bottomNavigationVisibility.hideBottomNavigation();
//init Views
Search = getActivity().findViewById(R.id.search_editText);
back = getActivity().findViewById(R.id.back);
recyclerView = getActivity().findViewById(R.id.recyclerView);
gridLayoutManager = new GridLayoutManager(getContext(),2,GridLayoutManager.VERTICAL,false);
recyclerView.setLayoutManager(gridLayoutManager);
//getting Data from Database
getDataFromDB();
//click handle, back
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bottomNavigationVisibility.showBottomNavigation();
NavController navController = Navigation.findNavController(getActivity(), R.id.nav_host_fragment);
navController.navigate(R.id.navigation_home);
}
});
}
private void getDataFromDB(){
postItem = new ArrayList<>();
//initialize database
reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot dataSnapshot: snapshot.getChildren()){
Post post = dataSnapshot.getValue(Post.class);
if(post.getCategory().equals("Skills, M" ) || post.getCategory().equals("Skills, S"))
postItem.add(post);
}
adapter = new postAdapter(getContext(),postItem);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(getContext(),"Something went Wrong",Toast.LENGTH_SHORT).show();
}
});
}
}
my adapter code:
public class postAdapter extends RecyclerView.Adapter<postAdapter.PostViewHolder> {
LayoutInflater mInflater;
private ArrayList<Post> mPost;
Context context;
public postAdapter(Context context, ArrayList<Post> posts) {
mInflater = LayoutInflater.from(context);
this.mPost = posts;
this.context=context;
}
#NonNull
#Override
public PostViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.list_item,parent,false);
return new PostViewHolder(itemView,this);
}
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onBindViewHolder(#NonNull PostViewHolder holder, int position) {
//setting post title
Post currentPost = mPost.get(position);
holder.itemNameTextView.setText(currentPost.getPost_Title());
//setting InExchange
if(currentPost.getCategory().equals("Skills, M") || currentPost.getCategory().equals("Educational Accessories, M")){
holder.inExchangeTextView.setText("Rs. " + currentPost.getIn_Exchange());
holder.inExchangeTextView.setTextColor(context.getColor(R.color.blue));
holder.exchangeIcon.setVisibility(View.VISIBLE);
}
else if(currentPost.getCategory().equals("Skills, S") || currentPost.getCategory().equals("Educational Accessories, A")){
holder.inExchangeTextView.setText(currentPost.getIn_Exchange());
holder.inExchangeTextView.setTextColor(context.getColor(R.color.blue));
holder.exchangeIcon.setVisibility(View.VISIBLE);
}
else{
holder.inExchangeTextView.setText(currentPost.getIn_Exchange());
holder.inExchangeTextView.setTextColor(context.getColor(R.color.green));
holder.exchangeIcon.setVisibility(View.INVISIBLE);
}
//setting image
Picasso.get().load(currentPost.getImage_Url_1()).into(holder.image);
holder.image.setClipToOutline(true);
//setting institution name
FirebaseDatabase.getInstance().getReference("Users/"+currentPost.getUid()+"/").getRef().addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
holder.institutionName.setText(snapshot.child("institution").getValue(String.class));
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(context,"Something went wrong",Toast.LENGTH_SHORT).show();
}
});
//handle click of item
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Bundle bundle = new Bundle();
bundle.putSerializable("currentPost", currentPost);
Navigation.findNavController(view).navigate(R.id.action_navigation_home_to_homeDetailFragment, bundle);
}
});
}
#Override
public int getItemCount() {
return mPost.size();
}
class PostViewHolder extends RecyclerView.ViewHolder{
TextView itemNameTextView;
TextView inExchangeTextView ;
TextView institutionName;
ImageView image, exchangeIcon ;
RecyclerView.Adapter mAdapter;
public PostViewHolder(#NonNull View itemView, postAdapter adapter) {
super(itemView);
itemNameTextView = itemView.findViewById(R.id.itemName_TextView);
inExchangeTextView = itemView.findViewById(R.id.inExchange_TextView);
image = itemView.findViewById(R.id.imageView);
institutionName = itemView.findViewById(R.id.institutionName);
exchangeIcon = itemView.findViewById(R.id.exchange_icon);
mAdapter = adapter;
}
}
}
my XML :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.home.HomeSkillsFragment">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/constraintLayoutTop"
android:layout_width="match_parent"
android:layout_height="#dimen/_130sdp"
android:background="#drawable/top_background_rounded"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/_10sdp"
android:layout_marginStart="#dimen/_12sdp"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:src="#drawable/arrow_back"
android:padding="#dimen/_8sdp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="#+id/search_editText"
style="#style/searchView"
android:layout_width="0dp"
android:layout_height="#dimen/_35sdp"
android:layout_marginStart="#dimen/_10sdp"
android:layout_marginTop="#dimen/_8sdp"
android:inputType="text"
android:includeFontPadding="false"
android:singleLine="true"
android:layout_marginEnd="#dimen/_16sdp"
android:layout_marginBottom="#dimen/main_start_end_margin"
android:hint="Search"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/back"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/skills_imageView"
android:layout_width="#dimen/_50sdp"
android:layout_height="#dimen/_50sdp"
android:background="#drawable/searchview_bg"
android:src="#drawable/ic_skills"
android:scaleType="centerInside"
android:layout_marginTop="#dimen/_8sdp"
app:layout_constraintTop_toBottomOf="#id/search_editText"
app:layout_constraintEnd_toEndOf="#+id/constraintLayoutTop"
app:layout_constraintStart_toStartOf="#+id/constraintLayoutTop" />
<TextView
android:id="#+id/skills_TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/_4sdp"
android:fontFamily="#font/poppins_regular"
android:text="Skills"
android:textColor="#android:color/black"
android:textSize="#dimen/_12ssp"
android:includeFontPadding="false"
app:layout_constraintTop_toBottomOf="#id/skills_imageView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:id="#+id/inExchange_TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="In Exchange"
android:textSize="#dimen/_10ssp"
android:textColor="#color/black"
android:fontFamily="#font/poppins_medium"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/constraintLayoutTop"
android:layout_marginTop="#dimen/_8sdp" />
<RadioGroup
android:id="#+id/radioGroup"
android:layout_width="wrap_content"
android:layout_height="#dimen/_20sdp"
app:layout_constraintTop_toBottomOf="#id/inExchange_TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:orientation="horizontal">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="See All"
android:scaleX="0.9"
android:scaleY="0.9"
android:textStyle="bold"
style="#style/radioButton"
android:fontFamily="#font/poppins_medium"
android:includeFontPadding="false"
android:id="#+id/radioButtonAll"
android:checked="true"
android:textSize="#dimen/_10sdp" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Give Money"
style="#style/radioButton"
android:scaleX="0.9"
android:scaleY="0.9"
android:textStyle="bold"
android:includeFontPadding="false"
android:fontFamily="#font/poppins_medium"
android:id="#+id/radioButtonMoney"
android:checked="false"
android:textSize="#dimen/_10sdp" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:scaleX="0.9"
android:scaleY="0.9"
android:text="Teach Other Skill"
style="#style/radioButton"
android:textStyle="bold"
android:fontFamily="#font/poppins_medium"
android:id="#+id/radioButtonSkill"
android:checked="false"
android:textSize="#dimen/_10sdp" />
</RadioGroup>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="#dimen/_10sdp"
android:paddingLeft="#dimen/_12sdp"
android:paddingRight="#dimen/_12sdp"
android:paddingTop="#dimen/_8sdp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/radioGroup"
app:layout_constraintVertical_weight="1" />
</androidx.constraintlayout.widget.ConstraintLayout>
In your code, you will try to get views from an activity, but not from a Fragment.
Search = getActivity().findViewById(R.id.search_editText);
back = getActivity().findViewById(R.id.back);
recyclerView = getActivity().findViewById(R.id.recyclerView);
And instead of onActivityCreated use onViewCreated
Updated HomeSkillFragment.class.
public class HomeSkillsFragment extends Fragment {
private EditText Search;
private ImageView back;
private RecyclerView recyclerView;
private ArrayList<Post> postItem;
private postAdapter adapter;
private GridLayoutManager gridLayoutManager;
private DatabaseReference reference;
private BottomNavigationVisibility bottomNavigationVisibility;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home_skills, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
bottomNavigationVisibility = new BottomNavigationVisibility(getActivity());
bottomNavigationVisibility.hideBottomNavigation();
//init Views
Search = view.findViewById(R.id.search_editText);
back = view.findViewById(R.id.back);
recyclerView = view.findViewById(R.id.recyclerView);
gridLayoutManager = new GridLayoutManager(getContext(), 2, GridLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(gridLayoutManager);
//getting Data from Database
getDataFromDB();
//click handle, back
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bottomNavigationVisibility.showBottomNavigation();
NavController navController = Navigation.findNavController(getActivity(), R.id.nav_host_fragment);
navController.navigate(R.id.navigation_home);
}
});
}
private void getDataFromDB() {
postItem = new ArrayList<>();
//initialize database
reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Post post = dataSnapshot.getValue(Post.class);
if (post.getCategory().equals("Skills, M") || post.getCategory().equals("Skills, S"))
postItem.add(post);
}
adapter = new postAdapter(getContext(), postItem);
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(getContext(), "Something went Wrong", Toast.LENGTH_SHORT).show();
}
});
}
}
I have seen all stack overflow question about this but can't find solution.
Getting error at this line.
String p_score = player_score_US.getText().toString();
My code
public class UpdateScore_activity extends AppCompatActivity {
private RecyclerView recyclerView2;
private DatabaseReference root=FirebaseDatabase.getInstance().getReference("A_matches&Score&contest").child("1").child("Score");
private us_adapter usAdapter;
private TextView playerName;
private Button SaveScorebtn;
public ArrayList<us_model> list1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.updatescore);
recyclerView2=findViewById(R.id.recycleview2);
SaveScorebtn=(Button)findViewById(R.id.us_saveScore);
EditText player_score_US=(EditText) findViewById(R.id.us_Player_Score12);
playerName=(TextView) findViewById(R.id.Player_Name);
list1=new ArrayList<>();
usAdapter=new us_adapter(this,list1);
recyclerView2.setAdapter(usAdapter);
recyclerView2.setLayoutManager(new LinearLayoutManager(this));
root.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot: snapshot.getChildren()){
String name1 = dataSnapshot.child("Name").getValue(String.class);
us_model myModel=new us_model(name1);
list1.add(myModel);
}
usAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(UpdateScore_activity.this, "hello", Toast.LENGTH_SHORT).show();
}
});
SaveScorebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String p_score = player_score_US.getText().toString();
HashMap<String, String> usermap = new HashMap<>();
usermap.put("Score",p_score);
for (int i=1;i<4;i++){
root.child(String.valueOf(i)).setValue(usermap);
}
openMain();
}
});
}}
Layout file of update Score Activity(Recyclerview)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
tools:context=".MainActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="500dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Match_Name"
android:gravity="center_horizontal"
android:text="Update Score"
android:textAlignment="center"
android:textColor="#000002"
android:textSize="32dp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="456dp"
android:layout_marginTop="10dp">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycleview2"
android:layout_width="match_parent"
android:layout_height="441dp" />
</LinearLayout>
<Button
android:id="#+id/us_saveScore"
android:layout_width="127dp"
android:layout_height="match_parent"
android:layout_marginLeft="62pt"
android:layout_marginTop="5dp"
android:layout_marginRight="57dp"
android:background="#FF80AB"
android:text="Save Score"
android:textStyle="bold" />
</LinearLayout>
</ScrollView>
</LinearLayout>
Layout file of player card
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="115dp"
android:layout_marginTop="10dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="111dp"
app:cardBackgroundColor="#A6D673">
<TextView
android:id="#+id/Player_Name"
android:layout_width="256dp"
android:layout_height="71dp"
android:layout_marginLeft="18dp"
android:layout_marginTop="12dp"
android:gravity="center"
android:text="Player Name"
android:textColor="#000000"
android:textSize="25dp"
android:textStyle="bold" />
<EditText
android:id="#+id/us_Player_Score12"
android:layout_width="79dp"
android:layout_height="61dp"
android:layout_marginLeft="300dp"
android:layout_marginTop="19dp"
android:gravity="center_horizontal"
android:textAlignment="center"
android:textColor="#000000"
android:hint="Enter"
android:textSize="22dp"
android:textStyle="bold" />
</androidx.cardview.widget.CardView>
</LinearLayout>
Adapter class
public class us_adapter extends RecyclerView.Adapter<us_adapter.Myviewholder> {
ArrayList<us_model> mlist1;
Context context;
public us_adapter(Context context, ArrayList<us_model> mlist1){
this.context=context;
this.mlist1=mlist1;
}
public us_adapter.Myviewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v=LayoutInflater.from(context).inflate(R.layout.updatescore_row,parent,false);
return new Myviewholder(v);
}
#Override
public void onBindViewHolder(#NonNull Myviewholder holder, int position) {
us_model model1 =mlist1.get(position);
holder.Name.setText(model1.getName());
}
public int getItemCount() {
return mlist1.size();
}
public class Myviewholder extends RecyclerView.ViewHolder {
TextView Name;
Button update;
public Myviewholder(#NonNull View itemView) {
super(itemView);
Name=itemView.findViewById(R.id.Player_Name);
}
}
}
Model class
public class us_model{
private String Name;
public us_model(String Name) {
this.Name = Name;
}
public String getName() {
return Name;
}
}
There are two solutions that you could try for this problem.
Solution 1:
From
EditText player_score_US=(EditText) findViewById(R.id.us_Player_Score12);
To
final EditText player_score_US=(EditText) findViewById(R.id.us_Player_Score12);
The reason is, if two methods see the same local variable in Java, Java wants you to ensure you will not change it, In that case you have to make it final.
Solution 2:
As well as, you could make it a global variable.
public class UpdateScore_activity extends AppCompatActivity {
private RecyclerView recyclerView2;
private DatabaseReference root=FirebaseDatabase.getInstance().getReference("A_matches&Score&contest").child("1").child("Score");
private us_adapter usAdapter;
private TextView playerName;
private Button SaveScorebtn;
private EditText player_score_US;
public ArrayList<us_model> list1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.updatescore);
recyclerView2=findViewById(R.id.recycleview2);
SaveScorebtn=(Button)findViewById(R.id.us_saveScore);
player_score_US=(EditText) findViewById(R.id.us_Player_Score12);
playerName=(TextView) findViewById(R.id.Player_Name);
list1=new ArrayList<>();
usAdapter=new us_adapter(this,list1);
recyclerView2.setAdapter(usAdapter);
recyclerView2.setLayoutManager(new LinearLayoutManager(this));
root.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot: snapshot.getChildren()){
String name1 = dataSnapshot.child("Name").getValue(String.class);
us_model myModel=new us_model(name1);
list1.add(myModel);
}
usAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(UpdateScore_activity.this, "hello", Toast.LENGTH_SHORT).show();
}
});
SaveScorebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String p_score = player_score_US.getText().toString();
HashMap<String, String> usermap = new HashMap<>();
usermap.put("Score",p_score);
for (int i=1;i<4;i++){
root.child(String.valueOf(i)).setValue(usermap);
}
openMain();
}
});
}}
Here is my recyclerView Adapter which shows a list from the database, View button is for downloading and the delete button deletes the file from device storage, it works perfectly. But how can I set Visibility of the delete button invisible/gone, if the file does not exist in the device storage.
MainActivity mainActivity;
ArrayList<DownModel> downModels;
public MyAdapter(MainActivity mainActivity, ArrayList<DownModel> downModels) {
this.mainActivity =mainActivity;
this.downModels = downModels;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater layoutInflater = LayoutInflater.from(mainActivity.getBaseContext());
View view = layoutInflater.inflate(R.layout.elements, viewGroup, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final MyViewHolder myViewHolder, final int i) {
myViewHolder.mName.setText(downModels.get(i).getName());
myViewHolder.mDownload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(myViewHolder.mDownload.getContext(), PdfView.class);
intent.putExtra("pdf_url", downModels.get(i).getLink());
intent.putExtra("pdf_name",downModels.get(i).getName());
myViewHolder.mDownload.getContext().startActivity(intent);
}
});
myViewHolder.mDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Context context = myViewHolder.itemView.getContext();
String pdfName = downModels.get(i).getName()+".pdf";
File file = new File(context.getFilesDir(), pdfName);
try {
if (file.exists())
file.delete();
Log.e("file","file"+file.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
#Override
public int getItemCount() {
return downModels.size();
}
}
RecyclerView
public class MainActivity extends AppCompatActivity {
FirebaseFirestore db;
RecyclerView mRecyclerView;
ArrayList<DownModel> downModelArrayList = new ArrayList<>();
MyAdapter myAdapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView= findViewById(R.id.recycle);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
db=FirebaseFirestore.getInstance();
dataFromFirebase();
}
#Override
protected void onResume() {
super.onResume();
myAdapter.notifyDataSetChanged();
}
private void dataFromFirebase() {
if(downModelArrayList.size()>0)
downModelArrayList.clear();
db.collection("chapter1").orderBy("value")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
for(DocumentSnapshot documentSnapshot: Objects.requireNonNull(task.getResult())) {
DownModel downModel= new DownModel(documentSnapshot.getString("name"),
documentSnapshot.getString("link"));
downModelArrayList.add(downModel);
}
myAdapter= new MyAdapter(MainActivity.this,downModelArrayList);
mRecyclerView.setAdapter(myAdapter);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, "Error ;-.-;", Toast.LENGTH_SHORT).show();
}
})
;
}
}
Layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp">
<TextView
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:text="Name"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:orientation="horizontal"
android:weightSum="2"
>
<Button
android:id="#+id/down"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_marginEnd="10dp"
android:layout_weight="1"
android:background="#A00303"
android:elevation="7dp"
android:text="View"
android:textColor="#FFFFFF"
tools:visibility="visible" />
<Button
android:id="#+id/delete"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:background="#A00303"
android:elevation="7dp"
android:text="Delete"
android:textColor="#FFFFFF"
tools:visibility="gone" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
Check if file exists in onBindViewHolder():
#Override
public void onBindViewHolder(#NonNull final MyViewHolder myViewHolder, final int i) {
//check if file exists
Context context = myViewHolder.itemView.getContext();
String pdfName = downModels.get(i).getName()+".pdf";
File file = new File(context.getFilesDir(), pdfName);
if(file.exits()){
//file exists, show delete button
myViewHolder.mDelete.setVisibility(View.VISIBLE);
}else{
//file doesn't exist, hide delete button
myViewHolder.mDelete.setVisibility(View.GONE);
}
.........
.........
.........
}
UPDATE:
After the download is complete call this method on the adapter:
adapter.notifyDataSetChanged();
UPDATE 2:
#Override
protected void onResume() {
super.onResume();
if(myAdapter != null){
myAdapter.notifyDataSetChanged();
}
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
I'm having these error on my coding
Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference onBindViewHolder(BrandAdapter.java:67) and
BrandAdapter.onBindViewHolder(BrandAdapter.java:34).
I'm not really sure what went wrong as I follow the tutorial very closely. And my database is not empty.
It contains child.
this is my adapter class
public class BrandAdapter extends RecyclerView.Adapter<BrandAdapter.MyViewHolder> {
private Context context;
List<String> key;
ArrayList<Brand> brandList;
public BrandAdapter(ArrayList<Brand> brandList) {
this.brandList = brandList;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.brand_list, viewGroup, false);
context = viewGroup.getContext();
return new BrandAdapter.MyViewHolder(view);
}
public BrandAdapter(Context c) {
this.context = c;
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, final int i) {
myViewHolder.brand_name.setText(brandList.get(i).getBrand_name());
Picasso.with(context).load(brandList.get(i).getBrand_image()).into(myViewHolder.image);
// Picasso.with(mcontext).load(brand.getBrand_image()).into(myViewHolder.image);
myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String bName = brandList.get(i).getBrand_name();
String pic = brandList.get(i).getBrand_image();
Log.i("loz", bName);
Intent intent = new Intent(context, updateBrand.class);
intent.putExtra("brand_name", bName);
intent.putExtra("imgurl", pic);
context.startActivity(intent);
}
});
#Override
public int getItemCount() {
return brandList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView brand_name;
CardView brand_cv;
ImageView image, btnDelete;
LinearLayout frame_layout;
public MyViewHolder(View itemView) {
super(itemView);
brand_name = itemView.findViewById(R.id.name);
image = itemView.findViewById(R.id.image);
brand_cv = itemView.findViewById(R.id.brand_cv);
btnDelete = itemView.findViewById(R.id.delete);
frame_layout = itemView.findViewById(R.id.frame_layout);
}
}
}
my Brand Activity class
public class BrandActivity extends AppCompatActivity {
DatabaseReference databaseReference;
ArrayList<Brand> brandList;
RecyclerView recyclerView;
SearchView searchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_brand);
databaseReference = FirebaseDatabase.getInstance().getReference("Brand").child("");
recyclerView = findViewById(R.id.rv);
searchView = findViewById(R.id.searchView);
}
#Override
protected void onStart() {
super.onStart();
if (databaseReference != null) {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
brandList = new ArrayList<>();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
brandList.add(ds.getValue(Brand.class));
}
}
BrandAdapter brandAdapter = new BrandAdapter(brandList);
recyclerView.setAdapter(brandAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(BrandActivity.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
app:cardElevation="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#color/lightgray">
<TextView
android:id="#+id/brand_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="sample"
android:textStyle="bold"
android:textColor="#color/white"
android:textAlignment="center"
android:background="#color/black"
android:textSize="20sp"
android:textAppearance="#style/TextAppearance.AppCompat.Headline" />
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="#FCFAFA"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:orientation="horizontal">
<ImageView
android:id="#+id/delete"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:padding="8dp"
android:visibility="visible"
app:srcCompat="#drawable/trash" />
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000" />
</androidx.cardview.widget.CardView>
Brand model
public class Brand {
public String brand_id;
public String brand_name;
public String brand_image;
public Brand(){}
public Brand(String brand_id, String brand_name, String brand_image) {
this.brand_id = brand_id;
this.brand_name = brand_name;
this.brand_image = brand_image;
}
public String getBrand_id() {
return brand_id;
}
public void setBrand_id(String brand_id) {
this.brand_id = brand_id;
}
public String getBrand_name() {
return brand_name;
}
public void setBrand_name(String brand_name) {
this.brand_name = brand_name;
}
public String getBrand_image() {
return brand_image;
}
public void setBrand_image(String brand_image) {
this.brand_image = brand_image;
}
}
In your MyViewHolder you are trying to find view that doesn't exist in your layout. So, try to change brand_name = itemView.findViewById(R.id.name) to brand_name = itemView.findViewById(R.id.brand_name). The same problem is also related to the other views in layout except image and delete: you don't have views with brand_cv and frame_layout ids.