Я разрабатываю приложение на основе размещения. Для этого я использовал базу данных Firebase в реальном времени. Я сопоставляю название компании из базы данных «Вакансия» и «Поданный кандидат», так что будут отображаться только сведения о подавших заявку кандидатах для этой конкретной компании. Все работает нормально, но проблема в том, что данные recyclerview загружаются только при втором нажатии кнопки.
public class AppliedCandidateActivity extends AppCompatActivity {
Toolbar toolbarAppliedcandidate;
RecyclerView rvAppliedCandidate;
List<appliedData> ls;
String compNameposted;
AppCandidateAdapter adapter;
DatabaseReference dbJobPost,dbAppliedCandidate;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.applied_candidate);
toolbarAppliedcandidate = findViewById(R.id.toolbarAppliedcandidate);
rvAppliedCandidate = findViewById(R.id.rvAppliedCandidate);
setSupportActionBar(toolbarAppliedcandidate);
getSupportActionBar().setTitle("Applied Candidate");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
rvAppliedCandidate.setHasFixedSize(true);
rvAppliedCandidate.setLayoutManager(new LinearLayoutManager(this));
ls = new ArrayList<>();
adapter = new AppCandidateAdapter(getApplicationContext(),ls);
rvAppliedCandidate.setAdapter(adapter);
getCompany();
matchCompanyName();
}
void getCompany()
{
//To retrieve company name
dbJobPost = FirebaseDatabase.getInstance().getReference("Job Post").child(FirebaseAuth.getInstance().getCurrentUser().getUid());
dbJobPost.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for (DataSnapshot ds : snapshot.getChildren())
{
PostJobData postJobData = ds.getValue(PostJobData.class);
compNameposted = postJobData.getCompName().toString();
//Toast.makeText(getApplicationContext(),postJobData.getCompName(),Toast.LENGTH_LONG).show();
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
void matchCompanyName()
{
//To retrieve data of applied candidate for particular company
dbAppliedCandidate = FirebaseDatabase.getInstance().getReference("Applied Candidate");
dbAppliedCandidate.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for (DataSnapshot ds: snapshot.getChildren())
{
for (DataSnapshot ds1 : ds.getChildren())
{
appliedData data = ds1.getValue(appliedData.class);
String compName = data.getCompName().toString();
//Toast.makeText(getApplicationContext(),compName,Toast.LENGTH_LONG).show();
if (compName.equals(compNameposted))
{
ls.add(data);
}
else if (ls.isEmpty()== true){
Toasty.info(AppliedCandidateActivity.this,"No One Applied Yet!!",Toast.LENGTH_LONG,true).show();
}
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
public class AppCandidateAdapter extends RecyclerView.Adapter<AppCandidateAdapter.AppCandidateViewHolder>{
List<appliedData> appliedDataList;
Context context;
public AppCandidateAdapter(Context mcontext,List list){
this.context = mcontext;
this.appliedDataList = list;
}
@NonNull
@Override
public AppCandidateViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.applied_candidate_compside,parent,false);
return new AppCandidateViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull AppCandidateViewHolder holder, int position) {
appliedData data = appliedDataList.get(position);
holder.tvCandidateName.setText(data.getName());
holder.tvCandidateAppliedPost.setText(data.getPosition());
holder.tvCandidateQual.setText(data.getQualification());
holder.tvCandidateSkills.setText(data.getSkills());
}
@Override
public int getItemCount() {
return appliedDataList.size();
}
class AppCandidateViewHolder extends RecyclerView.ViewHolder{
TextView tvCandidateName,tvCandidateAppliedPost,tvCandidateQual,tvCandidateSkills;
Button btnDeleteCandidate,btnSendMail;
public AppCandidateViewHolder(@NonNull View itemView) {
super(itemView);
tvCandidateName = itemView.findViewById(R.id.tvCandidateName);
tvCandidateAppliedPost = itemView.findViewById(R.id.tvCandidateAppliedPost);
tvCandidateQual = itemView.findViewById(R.id.tvCandidateQual);
tvCandidateSkills = itemView.findViewById(R.id.tvCandidateSkills);
btnDeleteCandidate = itemView.findViewById(R.id.btnDeleteCandidate);
btnSendMail = itemView.findViewById(R.id.btnSendMail);
}
}
}
}
Пожалуйста, никогда не оставляйте onCancelled
пустым, так как вы игнорируете возможные ошибки. Его минимальная реализация должна быть: public void onCancelled(@NonNull DatabaseError databaseError) { throw databaseError.toException(); }
Предполагая, что ваш onDataChange
вызывается, успешно считывает данные PostJobData
из моментального снимка и добавляет их в ls
, вы не сообщаете Android, что список изменился. Только после того, как вы уведомите адаптер об изменении, он повторно отобразит представление.
dbJobPost = FirebaseDatabase.getInstance().getReference("Job Post").child(FirebaseAuth.getInstance().getCurrentUser().getUid());
dbJobPost.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for (DataSnapshot ds : snapshot.getChildren()) {
PostJobData postJobData = ds.getValue(PostJobData.class);
compNameposted = postJobData.getCompName().toString();
}
adapter.notifyDataSetChanged(); // notify the adapter
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
throw error.toException(); // never ignore errors
}
});
Он не работает должным образом, и цикл else также выполняется одновременно. Та же проблема продолжается
Вам придется сделать немного лучше, чем «это не работает». Твоему onChange
звонят? Если да, и вы выполняете его в отладчике, зацикливается ли он? Получает ли он postJobData
, как вы ожидали? Достигает ли он (нового) вызова notifyDataSetChanged
? Если вы не расскажете нам, что именно происходит, вряд ли кто-нибудь обнаружит больше проблем на этом этапе, чем то, что уже сделал я (и ADM).
Все работает нормально. Единственная проблема заключается в том, что данные отображаются только при нажатии кнопки 2-й раз
Вы проходили код в отладчике? Достиг ли он (нового) вызова notifyDataSetChanged
? Это должно обновить адаптер.
Да, сэр, он проходит через «notifyDataSetChanged». Но это когда-то работает, а когда-то не работает
Так это отличается от того, что было раньше, не так ли? Если это так, это указывает на то, что notifyDataSetChanged
имеет значение, и это хорошо. В этот момент вам нужно будет выяснить, в чем разница между тем, когда это работает, и когда это не работает. Stack Overflow — заведомо неэффективный интерактивный отладчик, поэтому я рекомендую проверить все переменные, пройтись по всем методам и посмотреть, в чем разница.
Привет, @NishmithaNaik. Ты продвинулся в этом?
Вам нужно уведомить адаптер из
matchCompanyName
внутриonDataChange
, когда вы закончите добавлять данные в список, то есть после цикла for.