如何更新RecyclerView,每个项目每N秒出现一次?

时间:2015-10-19 22:31:23

标签: android adapter android-recyclerview

我想知道,如果它在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);
}

主要

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 个答案:

答案 0 :(得分:1)

我认为其中一个解决方案是制作两个ArrayLists并将文本从一个复制到另一个并继续通知适配器 - 如下所示:

制作两个数组:

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

使用ScheduledExecutorService或其他计时器。我会做这样的事情:

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()方法的末尾添加一些延迟机制。无论如何 - 祝你好运!