Android - listview的getView()等待返回,直到从firebase

时间:2016-09-25 04:24:33

标签: android listview firebase firebase-realtime-database

getView()方法

public View getView(final int position, View convertView, ViewGroup parent) {
    View view;

    if(convertView != null){
        view = convertView;
    }else{
        view = View.inflate(context, resLayout, null);
    }

    CircleImageView ivProfile = (CircleImageView) view.findViewById(R.id.ivProfile);
    tvName = (TextView) view.findViewById(R.id.tvName);
    tvMessage = (TextView) view.findViewById(R.id.tvLastMessage);
    tvDate = (TextView) view.findViewById(R.id.tvDate);

    setData(position);

    return view;
}

使用setData(位置)

private void setData(final int position){
    Query query_user = FirebaseDatabase.getInstance().getReference().child("Users").
            orderByChild("email").
            equalTo(listOfRooms.get(position).getRecipient());

    query_user.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            name = dataSnapshot.child("name").getValue().toString();

            //Log.d("LOG_ROOM", String.valueOf(listOfRooms.size() + "||" + position));
            //Log.d("LOG_ROOM", tvName.getText().toString() + "||" + tvMessage.getText().toString() + "||" + tvDate.getText().toString());

            tvName.setText(name);
            tvMessage.setText(listOfRooms.get(position).getListOfMessages().get(listOfRooms.get(position).getListOfMessages().size() - 1).getMessage());
            tvDate.setText(convertTimestampIntoDate(listOfRooms.get(position).getListOfMessages().
                    get(listOfRooms.get(position).getListOfMessages().size() -1).getTimestamp()));

            Log.d("LOG_FUNCTION", "onChildAdded Called" + ": " + name);
        }

        @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) {

        }
    });
}

我正在尝试将数据设置为listView的每个项目,但是当您看到setData(int)的方法时,该方法会处理UI的任务;它设置用户名,消息和日期textview的文本。但是,我发现这种编码存在问题。例如,可以从服务器加载两个数据,但在onChildAdded()方法中加载数据时,getView()的方法返回view,以便只有listView的最后一项1}}变了。 有没有办法补充这类问题?

the result

2 个答案:

答案 0 :(得分:0)

setData(position);将其带入后台主题。

public View getView(final int position, View convertView, ViewGroup parent) {
    View view;

    if(convertView != null){
        view = convertView;
    }else{
        view = View.inflate(context, resLayout, null);
    }

    CircleImageView ivProfile = (CircleImageView) view.findViewById(R.id.ivProfile);
    tvName = (TextView) view.findViewById(R.id.tvName);
    tvMessage = (TextView) view.findViewById(R.id.tvLastMessage);
    tvDate = (TextView) view.findViewById(R.id.tvDate);

    //setData(position);
    new SetInBackAsyncTask(position).execute();

    return view;
    }
class SetInBackAsyncTask extends AsyncTask<String, String, String> {

    int pos;
    SetInBackAsyncTask(int pos){
       this.pos =pos;
      }
    protected void OnPreExecute(){}
    protected String doInBackground(String... params) { 
         setData(pos);
    }
    protected void onPostExecute(String file_url) { }
}

答案 1 :(得分:0)

使用handler等待从firebase获取数据

   // construct the handler inside your adapter's constructor so you know it is on the UI thread
   Handler myHandler = new Handler(); 

class LoadData implements Runnable {
  TextView tvName, tvMessage, tvDate;
  int position;

 public LoadData(TextView tvName, TextView tvMessage, TextView tvDate, int position) {
  this.tvName = tvName;
  this.tvMessage = tvMessage;
  this.tvDate = tvDate;
  this.position = position;
 }

 @Override
 public void run() {

  // keep your Set data stuff her and pass reference of your textviews
  setData(position, tvName, tvDate, tvMessage);

}
}

这里有一些重要的事情,最好总是在getView方法中使用holder类,而不是每次调用getView都会导致视图膨胀,这可能会导致性能问题:

public View getView(final int position, View convertView, ViewGroup parent) {

final ViewHolder viewHolder;
View view = convertView;

if(view != null){
    //view = convertView;
    viewHolder = (ViewHolder) view.getTag();
    //Change is here
    myHandler.removeCallbacks(viewHolder.mRunnable);
}else{
    //view = View.inflate(context, resLayout, null);
    view = LayoutInflater.from(mContext).inflate(resLayout, parent, false);
    viewHolder.ivProfile = (CircleImageView) view.findViewById(R.id.ivProfile);
    viewHolder.tvName = (TextView) view.findViewById(R.id.tvName);
    viewHolder.tvMessage = (TextView) view.findViewById(R.id.tvLastMessage);
    viewHolder.tvDate = (TextView) view.findViewById(R.id.tvDate);
   //Change is here
   viewHolder.mRunnable = new LoadData(viewHolder.tvName, viewHolder.tvMessage, viewHolder.tvDate, position);
}

//setData(position);
//Change is here
 myHandler.postDelayed(viewHolder.mRunnable, 3000);

 return view;
}

你的持有者类就像你的适配器类的子类:

 private static class ViewHolder {
    CircleImageView ivProfile;
    TextView tvName, tvMessage, tvDate;
}