2016-04-05 11 views
0

RecyclerViewをスクロールしてバックアップするたびに、データが変更されたときにレイアウトが誤った項目に変わります。私はスポーツのスコアを表示しているので、ゲームが生きているときは、それが見えなくなっていることに気づいたときです。私はこれに対する他の答えを見てきましたが、誰も私がこれを修正するために追加/変更する必要があるものを特定するのを助けてくれなかったので、コードを投稿することで誰かが私が間違っていることを示すことができます。ここにドロップボックスlinkがありますので、私のスクリーンショットを見ることができます。写真は下から上にスワイプする間に交互に表示されます(最後の2枚の写真を除いて、Dropboxは何らかの理由で注文を変更しました)。コードは、RecyclerViewリストにデータを表示(バインド)しますが、スクロールアップ時に表示設定を壊します。

これはViewHolder(長い変数名のために申し訳ありませんが、それは私のために明確なものを保持します)にデータをバインドする私のコードです:

public class NBAGameHolder extends GameHolder implements View.OnClickListener 
{ 
    /*NOTE: ONCE A GAME BEGINS: 
    /  mGameStartTimeAndHomeScore will be used to display the home team score. 
    /  mHomeTeamRecordAndQuarter will display the current quarter. 
    /  mAwayTeamRecordAndTimeRem will display the time remaining in the quarter 
    */ 

    private TextView mHomeTeam, mAwayTeam, mGameStartTimeAndHomeScore; 
    private TextView mHomeTeamRecordAndQuarter, mAwayTeamRecordAndTimeRem, mAwayTeamScore, mFinalHeader; 
    private ImageView mHomeTeamLogo, mAwayTeamLogo; 
    private int mGreen, mDefaultGray; 

    private Context mContext; 

    public NBAGameHolder(View itemView, Context context) 
    { 
     super(itemView); 
     mContext = context; 
     itemView.setOnClickListener(this); 

     mHomeTeam = (TextView) itemView.findViewById(R.id.home_team_name); 
     mAwayTeam = (TextView) itemView.findViewById(R.id.away_team_name); 
     mHomeTeamLogo = (ImageView) itemView.findViewById(R.id.home_team_logo); 
     mAwayTeamLogo = (ImageView) itemView.findViewById(R.id.away_team_logo); 
     mGameStartTimeAndHomeScore = (TextView) itemView.findViewById(R.id.game_time_home_team_score); 
     mAwayTeamScore = (TextView) itemView.findViewById(R.id.away_team_score); 
     mHomeTeamRecordAndQuarter = (TextView) itemView.findViewById(R.id.home_team_record_quarter); 
     mAwayTeamRecordAndTimeRem = (TextView) itemView.findViewById(R.id.away_team_record_time_left_in_qrt); 
     mFinalHeader = (TextView) itemView.findViewById(R.id.nba_final_header_text_view); 
     mGreen = ContextCompat.getColor(mContext, R.color.green); 
     mDefaultGray = ContextCompat.getColor(mContext, android.R.color.darker_gray); 
    } 

    public void bindNBAGameData(NBAGame game) 
    { 
     Picasso.with(mContext).load(game.getHomeTeamLogoSrc()).fit().into(mHomeTeamLogo); 
     Picasso.with(mContext).load(game.getAwayTeamLogoSrc()).fit().into(mAwayTeamLogo); 
     mHomeTeam.setText(game.getHomeTeam()); 
     mAwayTeam.setText(game.getAwayTeam()); 

     if(!game.getHomeTeamScore().equals("") && !game.gameEnded())  //if the game is live 
     { 
      mGameStartTimeAndHomeScore.setText(game.getHomeTeamScore()); 
      mAwayTeamScore.setText(game.getAwayTeamScore()); 
      mHomeTeamRecordAndQuarter.setText(game.getQuarter()); 
      mAwayTeamRecordAndTimeRem.setText(game.getTimeLeft()); 
      mHomeTeamRecordAndQuarter.setTextColor(ContextCompat.getColor(mContext, R.color.orange)); 
      mAwayTeamRecordAndTimeRem.setTextColor(ContextCompat.getColor(mContext, R.color.orange)); 
      mHomeTeamRecordAndQuarter.setTextSize(16); 
      mAwayTeamRecordAndTimeRem.setTextSize(16); 
      mFinalHeader.setVisibility(View.GONE); 
     } 
     else if(game.gameEnded()) 
     { 
      mGameStartTime.setText(game.getHomeTeamScore()); 
      mAwayTeamScore.setText(game.getAwayTeamScore()); 
      int homeScore = Integer.parseInt(mGameStartTime.getText().toString()); 
      int awayScore = Integer.parseInt(mAwayTeamScore.getText().toString()); 
      mHomeTeamRecordAndQuarter.setText(game.getHomeTeamRecord()); 
      mHomeTeamRecordAndQuarter.setTextSize(12); 
      mAwayTeamRecordAndTimeRem.setText(game.getAwayTeamRecord()); 
      mAwayTeamRecordAndTimeRem.setTextSize(12); 
      mHomeTeamRecordAndQuarter.setTextColor(mDefaultGray); 
      mAwayTeamRecordAndTimeRem.setTextColor(mDefaultGray); 
      mFinalHeader.setVisibility(View.VISIBLE); 

      if(homeScore > awayScore) 
      { 
       mGameStartTimeAndHomeScore.setTextColor(mGreen); //displays winning team's score in green 
       mAwayTeamScore.setTextColor(mDefaultGray); //sets the losing team to the default dark gray color 
       mHomeTeam.setTextColor(mGreen); 
       mAwayTeam.setTextColor(mDefaultGray); 
      } 
      else 
      { 
       mAwayTeamScore.setTextColor(mGreen); 
       mGameStartTimeAndHomeScore.setTextColor(mDefaultGray); //sets the losing team to the default dark gray color 
       mAwayTeam.setTextColor(mGreen); 
       mHomeTeam.setTextColor(mDefaultGray); 
      } 
     } 
     else            //game has not started 
     { 
      mGameStartTimeAndHomeScore.setText(game.getGameStartTime()); 
      mHomeTeamRecordAndQuarter.setText(game.getHomeTeamRecord()); 
      mAwayTeamRecordAndTimeRem.setText(game.getAwayTeamRecord()); 
      mAwayTeamScore.setText("");   
      mFinalHeader.setVisibility(View.GONE); 
     } 
    } 

    @Override 
    public void onClick(View v) 
    { 

    } 
} 
+0

データ+ Recyclerviewを結合するための優れたチュートリアルでは、私はそれをやっている[ここ](http://chintanrathod.com/develop_apps_faster_using_data_binding_part2/) –

答えて

1
The issue is because of recycling of views. 
それでは、ここで起こっていることはワットに関連することが観察されたリスト項目のプロパティである

他の不要なリスト項目ビューのプロパティ

あなたの場合、リスト項目のすべてのビューに対してTextViewプロパティを設定する必要があります。

Example - 条件が満たされた場合にTextViewのテキストカラーを緑色にする場合は、elseブロックのTextViewのTextカラーもその場合のデフォルトカラーに設定する必要があります。

同様に、条件が満たされた場合にTextViewのTextサイズを変更する場合は、TextViewのTextサイズをelseブロックでも設定しなければなりません。

ビューを作成している場合は、同じアプローチをとる必要があります。VISIBLE/INVISIBLE/GONE上記いずれか

ステートメント場合は、このようなあなたのビューのデフォルトのプロパティを設定することができ、他の場合 -

mHomeTeamRecordAndQuarter.setTextColor();//Set default color here 
mAwayTeamRecordAndTimeRem.setTextColor(); //Set default color here 
mHomeTeamRecordAndQuarter.setTextSize(10);//Set default text size here 
mAwayTeamRecordAndTimeRem.setTextSize(10);//Set default text size here 
mFinalHeader.setVisibility(View.VISIBLE);//Set all those views visible here whose visibility is being changes in any of the if-else block 

をそして今、あなたは成功した場合、他のブロックにあなたの意見の特性を変化させることができます。 プロパティが変更されていないビューの場合、それらはデフォルトのプロパティを所有します。

+0

Okですが、ゲーム、終了したゲーム、および開始していないゲーム。それで私は 'bindNBAGameData()'の中に構造体を設定しました。だから、ゲームのタイムライン構造を維持しながら、私があなたが言っていることを達成する方法のコード例を挙げることができますか? –

+0

答えを編集しました。 –

+0

私はついにそれが働いた!ありがとうございました。あなたの答えはトンを助けました。私はそれをチェックしました。 –

0
このよう onBindViewHolder()方法 内部 Adapterクラス内部

バインドデータ:

@Override 
     public void onBindViewHolder(NBAGameHolder holder, int position) { 
      NBAGame game = itemsList.get(position); 
      holder.mGameStartTime.setText(game.getHomeTeamScore()); 
    } 
+0

ですが、私は(onBindViewHolder '' '内部holder.bindNBAGameData(ゲームを)呼んでいます) '。私はあなたの答えが働いているとは思わない。 –

+0

私はちょうどelseブロックが入れ子になっていることに気付きました。したがって、@ Shadab Ansariは、条件が偽であるときに外側のelseブロック内のデフォルト値に戻すべきです。 – asim13se

関連する問題