2016-09-25 12 views
0

getViewメソッドからロードされるようになるまで戻すために待機()メソッドアンドロイド - リストビューのgetViewメソッドは、()データがfirebase

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に設定します。しかし、私はこの種のコーディングで問題を発見しました。例えば、サーバから2つのデータをロードすることができるが、メソッドでデータをロードしている間に、getView()のメソッドはviewを返し、最後の項目はlistViewに変更される。 この種の問題を補う方法はありますか?

the result

+0

あなたが位置に基づいて独自のaddChildEventListenerを作成する必要があります。今は前回のポジションをオーバーライドしていて、最後のアイテムにロードしています。 – Jai

答えて

0

使用ハンドラはここ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メソッドにホルダークラスを使用するのではなくて、あなたのビューを膨張させるために、より良い習慣ですパフォーマンスの問題を引き起こす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; 
} 
+0

ありがとうございます – MyNameIsAsker

+0

@MyNameIsAsker: :) – Jai

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) { } 
} 
+0

私はUIスレッドがdoInBackground()によってアクセス可能ではないと考えています – MyNameIsAsker

+0

@MyNameIsAsker yes値を設定するときに、 'onPost.'にそれらの値を設定する' runOnUiThread'を使用します。 –

関連する問題