【问题标题】:Firebase Listview not displayed until open and close an ActivityFirebase Listview 在打开和关闭 Activity 之前不显示
【发布时间】:2017-10-30 15:50:30
【问题描述】:

我的 ListView 使用适配器并充满 Firebase 内容时遇到问题。但是在我打开一个活动并返回该活动之前,它不会在活动启动时出现。 这是我的 FirebaseHelper 代码

public class FirebaseHelper {
 DatabaseReference db;
QuestionAdapter adapter;
View v;
 ArrayList<Questions> questionEntries =new ArrayList<>();
public FirebaseHelper(DatabaseReference db)  {
    this.db=db;
    }

/*private void fetchData (DataSnapshot dataSnapshot){
questionEntries.clear();
    Questions questions = dataSnapshot.getValue(Questions.class);
    questionEntries.add(questions);}*/


public ArrayList<Questions> retreive (){
db.orderByChild("question_date").addChildEventListener(new ChildEventListener() {

    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        Questions questions =dataSnapshot.getValue(Questions.class);
        questionEntries.add(questions);

    }

    @Override
    public void onChildChanged(DataSnapshot dataSnapshot, String s){
    }

    @Override
    public void onChildRemoved(DataSnapshot dataSnapshot) {

    }

    @Override
    public void onChildMoved(DataSnapshot dataSnapshot, String s) {

    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});
return questionEntries;
}

}

这里是活动。 我尝试使用可见性仅在有内容时显示,但它并不总是有效 这是我的活动:

public class Actu extends Fragment {
private DatabaseReference db;
FirebaseHelper helper;
QuestionAdapter adapter;
ListView lv;
View v;

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    v = inflater.inflate(R.layout.activity_actu, container, false);
    lv = (ListView) v.findViewById(R.id.actu_rv);
    progressBar = (ProgressBar) v.findViewById(R.id.progress_bar);
    no_connection =(TextView) v.findViewById(R.id.no_connection);
    db = FirebaseDatabase.getInstance().getReference("Questions");
    db.limitToLast(100).orderByKey();
    helper = new FirebaseHelper(db);
    adapter = new QuestionAdapter(getContext(),helper.retreive());
    lv.setAdapter(adapter);



    return v;   
  }

编辑:

请帮帮我。

更新

 public QuestionAdapter(Context c, ArrayList<Questions> questionEntries) {
    this.c = c;
    this.questionEntries = questionEntries;
}

@Override
        public int getCount() {
            return questionEntries.size();
        }

        @Override
        public Object getItem(int position) {
            return questionEntries.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(final int position, View contentView, ViewGroup parent) {

            if (contentView==null){
                contentView= LayoutInflater.from(c).inflate(R.layout.actu_list_item,parent,false);
            }
            TextView asker = (TextView) contentView.findViewById(R.id.asker_name);
            TextView date = (TextView) contentView.findViewById(R.id.date);
            TextView title = (TextView) contentView.findViewById(R.id.question_title);
            TextView content = (TextView) contentView.findViewById(R.id.question_content);
            Button answer = (Button) contentView.findViewById(R.id.answer);
             final EditText answerET= (EditText)  contentView.findViewById(R.id.answer_edittext);

            posit = this.getItem(position);
            answer.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View view) {
                    answer_text = answerET.getText().toString();

                    if(answer_text.length()<20){
                        Toast.makeText(c,"Vous devez entrer au moins 20 cgharactères",Toast.LENGTH_LONG).show();
                    }else

                        {


                        Toast.makeText(c,"Post en cours...",Toast.LENGTH_LONG).show();
                        Answer answerClass = new Answer();
                        FirebaseDatabase database = FirebaseDatabase.getInstance();
                        FirebaseAuth firebaseAuth1 = FirebaseAuth.getInstance();
                        FirebaseUser firebaseUser= firebaseAuth1.getCurrentUser();
                        qe= (Questions) posit;
                        SimpleDateFormat dateFormat=new SimpleDateFormat("HH:mm dd-MM-yyyy");
                        String date= dateFormat.format(new Date(System.currentTimeMillis()));


                        assert  firebaseUser !=null;
                        DatabaseReference Asker = database.getReference(firebaseUser.getUid()+"/name");
                        Asker.addListenerForSingleValueEvent(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {
                                name = dataSnapshot.getValue(String.class);

                            }

                            @Override
                            public void onCancelled(DatabaseError databaseError) {

                            }
                        });
                        answerClass.setAnswer(answer_text);
                        answerClass.setUsername(name);
                        answerClass.setDate(date);
                        DatabaseReference AnswerRef =database.getReference("Questions/"+qe.getTag_id()+"/");
                        AnswerRef.push().setValue(answerClass).addOnCompleteListener(new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {
                                Toast.makeText(c,"Reponse postée",Toast.LENGTH_LONG).show();

                            }
                        });


                        }
                }
            });

            qe= (Questions) this.getItem(position);

//有错误 // 看起来 qe 是空的 asker.setText(qe.getQuestion_username()); date.setText(qe.getQuestion_date()); title.setText(String.format("Q: %s", qe.getQuestion_title())); content.setText(qe.getQuestion_content());

            contentView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(c,qe.getQuestion_username(),Toast.LENGTH_LONG).show();
                }
            });
            this.notifyDataSetChanged();

            return contentView;
        }

【问题讨论】:

    标签: android firebase


    【解决方案1】:

    你不能以你的方式返回questionEntriesArrayList。当你使用这行代码时:

    return questionEntries;
    

    Firebase 未完成从您的数据库中获取数据。这是因为onChildAdded() 方法的异步行为而发生的。所以要解决这个问题,请使用以下代码:

    db.orderByChild("question_date").addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            ArrayList<Questions> questionEntries = new ArrayList<>();
            Questions questions = dataSnapshot.getValue(Questions.class);
            questionEntries.add(questions);
            Log.d("TAG", questionEntries);
        }
    
        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s){}
    
        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {}
    
        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {}
    
        @Override
        public void onCancelled(DatabaseError databaseError) {}
    });
    

    Edit1:另一种方法是像这样使用ValueEventListener:

    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    DatabaseReference db = rootRef.child("Question");
    ValueEventListener eventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            ArrayList<Questions> questionEntries = new ArrayList<>();
            for(DataSnapshot ds : dataSnapshot.getChildren()) {
                Questions questions = ds.getValue(Questions.class);
                questionEntries.add(questions);
            }
            Log.d("TAG", questionEntries);
        }
    
        @Override
        public void onCancelled(DatabaseError databaseError) {}
    };
    db.addListenerForSingleValueEvent(eventListener);
    

    Edit2:假设 Question 节点是 Firebase 数据库根的直接子节点,另一种方法是:

    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    DatabaseReference db = rootRef.child("Question");
    ValueEventListener eventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            ArrayList<String> questionEntries = new ArrayList<>();
            for(DataSnapshot ds : dataSnapshot.getChildren()) {
                String question_title = ds.child("question_title").getValue(String.class);
                questionEntries.add(question_title);
            }
            Log.d("TAG", questionEntries);
        }
    
        @Override
        public void onCancelled(DatabaseError databaseError) {}
    };
    db.addListenerForSingleValueEvent(eventListener);
    

    【讨论】:

    • 我不明白。如果 Retrieve 方法返回 questionEntries,则应将其放置在哪里。据我所知,不可能在 onchildAdded 中声明 questionEntries 并将其返回给 Retrieve。
    • 不工作(没有显示)是另一种方法吗?请帮帮我。
    • 错误是什么?还请分享您的数据库结构。
    • 我应该把它放在我的活动或适配器中吗?
    • 让questionEntries 填充数据,是的,您应该将它与您的适配器一起使用。但请记住,仅在 onDataChange() 方法中使用适配器,就在这行代码之后:questionEntries.add(question_title);
    【解决方案2】:

    问题似乎与您的 questionEntries 列表有关。

    【讨论】:

    • 我收到 NullPointerExeption。
    • 对不起,可能不好。编辑答案。
    猜你喜欢
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多