2015-10-19 89 views
1

如何更新RecyclerView,讓每個項目每N秒出現一次?

我想知道,如果它是動態加載RecyclerView中的項目。

我希望做一個列表這樣的應用生命線example aplication

我嘗試使用

new android.os.Handler().postDelayed(
new Runnable() { 
    public void run() { 
     Log.i("tag", "This'll run 300 milliseconds later"); 
    } 
},300); 

,但它不適合我,因爲等那麼久,然後顯示所有在一次

這是我的代碼

public class TextoAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{ 

private static final int TYPE_BUTTON = 0; 
private static final int TYPE_TEXT = 1; 

private Context context; 
private int lastPosition = -1; 

@Override 
public int getItemViewType(int position) { 
    // Just as an example, return 0 or 2 depending on position 

    int viewType; 
    if (position % 2 * 2 == 0) 
    { 
     viewType = TYPE_TEXT; 
    }else 
    { 
     viewType = TYPE_BUTTON; 
    } 
    return TYPE_TEXT; 
} 

public static class TextoViewHolder extends RecyclerView.ViewHolder { 
    CardView cv; 
    TextView texto; 
    TextoViewHolder(View itemView) { 
     super(itemView); 
     cv = (CardView)itemView.findViewById(R.id.cv_texto); 
     texto = (TextView)itemView.findViewById(R.id.texto); 
    } 
} 

public static class ButtonViewHolder extends RecyclerView.ViewHolder { 
    CardView cv_btn; 
    Button izq, der; 
    ButtonViewHolder(View itemView) { 
     super(itemView); 
     cv_btn = (CardView)itemView.findViewById(R.id.cv_botones); 
     izq = (Button)itemView.findViewById(R.id.btn_izquierdo); 
     der = (Button)itemView.findViewById(R.id.btn_derecho); 
    } 
} 

List<Texto> textos; 
LinearLayoutManager llm; 
RecyclerView rv; 


public TextoAdapter(List<Texto> textos, LinearLayoutManager llm,RecyclerView rv,Context context){ 
    this.textos = textos; 
    this.llm = llm; 
    this.rv = rv; 
    this.context = context; 
} 

public void addItemsToList (Texto texto){ 
    textos.add(texto); 
    this.notifyDataSetChanged(); 
    rv.smoothScrollToPosition(getItemCount()); 

} 


@Override 
public int getItemCount() { 
    return textos.size(); 
} 

@Override 
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { 

    LayoutInflater mInflater = LayoutInflater.from (viewGroup.getContext()); 
    switch (viewType) { 

     case TYPE_TEXT: 
      View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.texto_card, viewGroup, false); 
      TextoViewHolder pvh = new TextoViewHolder(v); 
      return pvh; 
     case TYPE_BUTTON: 
      ViewGroup v2 = (ViewGroup) mInflater.inflate (R.layout.botones_card, viewGroup, false); 
      ButtonViewHolder vhGroup = new ButtonViewHolder(v2); 
      return vhGroup; 
     default: 
      View v3 = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.texto_card, viewGroup, false); 
      TextoViewHolder pvh3 = new TextoViewHolder(v3); 
      return pvh3; 
    } 


} 

@Override 
public void onBindViewHolder(RecyclerView.ViewHolder holder, int i) { 

    switch (holder.getItemViewType()) { 

     case TYPE_TEXT: 
      TextoViewHolder textoViewHolder = (TextoViewHolder) holder; 

      textoViewHolder.texto.setText(textos.get(i).texto); 
      setAnimation(textoViewHolder.cv, i); 
      textoViewHolder.cv.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        addItemsToList(new Texto("otroooooo")); 

       } 
      }); 
      break; 

     case TYPE_BUTTON: 

      ButtonViewHolder buttonViewHolder = (ButtonViewHolder) holder; 
      setAnimation(buttonViewHolder.cv_btn, i); 
      buttonViewHolder.izq.setText("SI"); 
      buttonViewHolder.der.setText("NO"); 

      break; 

    } 
} 

/** 
* Here is the key method to apply the animation 
*/ 
private void setAnimation(View viewToAnimate, int position) 
{ 
    // If the bound view wasn't previously displayed on screen, it's animated 
    if (position > lastPosition) 
    { 
     //Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left); 
     Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.fade_in); 
     animation.setDuration(1000); 
     viewToAnimate.startAnimation(animation); 
     lastPosition = position; 
    } 
} 


@Override 
public void onAttachedToRecyclerView(RecyclerView recyclerView) { 
    super.onAttachedToRecyclerView(recyclerView); 
} 

Main

public class MainActivity extends AppCompatActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    RecyclerView rv = (RecyclerView)findViewById(R.id.rv); 
    LinearLayoutManager llm = new LinearLayoutManager(this); 
    rv.setLayoutManager(llm); 

    List<Texto> textos; 

    textos = new ArrayList<>(); 

    textos.add(new Texto("Hola y bienvenido al juego")); 
    TextoAdapter adapterTextos = new TextoAdapter(textos,llm,rv,this); 
    rv.setAdapter(adapterTextos); 

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
    fab.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) 
        .setAction("Action", null).show(); 
     } 
    }); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_main, menu); 
    return true; 
} 


@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 

    //noinspection SimplifiableIfStatement 
    if (id == R.id.action_settings) { 
     return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 

感謝

回答

1

我認爲解決方案之一是進行兩次的ArrayList,並從一個到另一個複製文本,並保持通知適配器 - 是這樣的:

讓兩個數組:

ArrayList<String> textsQueue;  // put all the texts here 
ArrayList<String> textos;   // pass it to the adapter 

使用ScheduledExecutorService或其他計時器。我願意做somethinkg這樣的:

ScheduledExecutorService ses = Executors.newScheduledThreadPool(1); 
int currentTextNo = 0; 
Runnable nextText = new Runnable { 
    @Override 
    public void run() { 
     textos.add(textsQueue.get(currentTextNo)); 
     currentTextNo++; 
     adapter.notifyDataSetChanged(); 

     if (currentTextNo == textsQueue.size()) { 
      ses.shutdownNow(); 
     } 
    } 
}; 
// the parameters are: runnable, initial delay, period, time unit 
ses.scheduleAtFixedRate(nextText, 0, 300, TimeUnit.MILLISECONDS); 

我不知道這是否是最佳的解決方案,我沒有驗證碼,但我認爲它可以工作。 我認爲你甚至可以讓文本出現在隨機時間之後。要做到這一點,你可以 - 而且這只是我的猜測 - 而不是使用scheduleAtFixedRate使用scheduleWithFixedDelay,並在run()方法的末尾加上一些延遲機制。無論如何 - 祝你好運!

+0

另外,如果您想使用它,請閱讀更多關於ScheduledExecutorService的內容 - 我最近只使用了它一次,而且我不確定此解決方案是否最適合性能。 –

+0

謝謝:)它適用於我 – Omar92