Android Recyclerview,添加新项目,保持其余部分不变,滚动在同一个地方

时间:2017-02-11 02:52:58

标签: android android-recyclerview

要做一些背景,这样你就可以更好地描绘我需要完成的事情。

嗯,我正在读取数据库中的数据,这个数据变化相对较快,让我们说每30秒,我需要滚动回收器检查新数据并按下一些按钮,每次按下按钮,它改变它的颜色,但发生了两件事。

1-我每隔几秒就用一个计时器刷新回收器,所以,当我滚动它并刷新时,它将一直到第一个项目,这不可能发生,所以我需要一种方法来防止这种情况

2-来自数据库的每个数据都需要进行一些调整,为此,我按下一个按钮,当我按下它时,此按钮会改变它的颜色,所以我知道该按钮的动作已经完成,但是,每次定时器刷新回收器它不仅转到第一个项目,而且还将按钮转换为原始颜色,因为重新创建了包含数据库中数据的整个回收器,并且当计时器刷新回收器时,可能不会发生项目应该保持不变,只添加新的IF如果新的。

以下是适配器和Activity的代码,请提前感谢您的帮助。

这是适配器

    public class ComandaAdapter extends
    RecyclerView.Adapter<ComandaAdapter.ComandaAdapterViewHolder>
    implements View.OnClickListener{

private ArrayList<Comanda> list_comandas;
private Context context;
private View.OnClickListener listener;


public ComandaAdapter(Context con, ArrayList<Comanda> list) {
    this.context = con;
    this.list_comandas = list;
}

@Override
public ComandaAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.row, parent, false);


    return new ComandaAdapterViewHolder(itemView);
}

@Override
public void onBindViewHolder(ComandaAdapterViewHolder holder, int position) {

    Integer anchomanda = Math.round(context.getResources().getDimension(R.dimen.parents_size));

    // Llenar la información de cada item

    Comanda comanda = list_comandas.get(position);

    comanda.setNro_comanda(position+"");

    String cadena = comanda.getOrden();
    Integer tope = cadena.length();

    Boolean tijera_categoria=false;

    Boolean tijera_articulo=true;
    Boolean tijera_contorno=true;
    Boolean tijera_cambio =true;

    Integer indisup;
    Integer indiin =0;
    char apuntador;
    String Buscado ="";
    String Buscado_contorno="";
    String Buscado_categoria="";
    Integer id=0;

        holder.txt_comanda.setText(position+"");

        holder.txt_mesa.setText(comanda.getMesa());

        for (int i = 0; i < tope ; i++) {

            apuntador = cadena.charAt(i);

            if (Buscado.equals("Bebidas")){
                break;
            }
            else
            {
                if (apuntador == '$')
                {
                    break;
                }
                else
                {
                    //CUERPO PRINCIPAL DE EJECUCION

                    if (apuntador == '#' && !tijera_categoria)
                    {
                        if (i==0) {
                            indiin = i + 1;
                        }

                    }

                    if (apuntador == '!' && !tijera_categoria)
                    {
                        tijera_categoria=true;
                        tijera_articulo=false;
                        indisup=i;

                        id=i;

                        Buscado=cadena.substring(indiin,indisup);
                        indiin=indisup+1;

                        Buscado_categoria=Buscado;

                        holder.b[id].setId(id);

                    }

                    if (apuntador == '%' && !tijera_articulo)
                    {
                        indisup=i;
                        tijera_articulo=true;
                        tijera_contorno=false;

                        Buscado=cadena.substring(indiin,indisup);

                        indiin=indisup+1;

                        holder.b[id].setLayoutParams(new LinearLayout.LayoutParams(anchomanda, LinearLayout.LayoutParams.WRAP_CONTENT));
                        holder.b[id].setTextSize((context.getResources().getDimension(R.dimen.txt_size)) / 2);
                        if (Buscado_categoria.equals("Fondos")) {
                            holder.b[id].setBackgroundTintList(context.getResources().getColorStateList(R.color.fondos, null));
                        }
                        if (Buscado_categoria.equals("Entradas")) {
                            holder.b[id].setBackgroundTintList(context.getResources().getColorStateList(R.color.entradas, null));
                        }
                        if (Buscado_categoria.equals("Postres")) {
                            holder.b[id].setBackgroundTintList(context.getResources().getColorStateList(R.color.postres, null));
                        }
                        holder.b[id].setText(Buscado);
                        holder.lyocomanda.addView(holder.b[id]);

                    }

                    if (apuntador == '*' && !tijera_contorno)
                    {
                        indisup=i;
                        tijera_cambio=false;

                        Buscado=cadena.substring(indiin,indisup);
                        indiin=indisup+1;

                        if (!Buscado.equals("")) {
                            Buscado_contorno=Buscado;
                            holder.t[i].setText(Buscado);
                            holder.t[i].setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                            holder.t[i].setTextSize((context.getResources().getDimension(R.dimen.txt_size)) / 2);
                            holder.l[id].addView(holder.t[i]);
                        }

                    }

                    if (apuntador == '#' && !tijera_cambio)
                    {
                        indisup=i;
                        tijera_contorno=true;
                        tijera_cambio=true;
                        tijera_categoria=false;

                        Buscado=cadena.substring(indiin,indisup);
                        indiin=indisup+1;

                        if (!Buscado_contorno.equals("")) {
                            holder.l[id].setLayoutParams(new LinearLayout.LayoutParams(anchomanda, ViewGroup.LayoutParams.WRAP_CONTENT));
                            holder.l[id].setOrientation(LinearLayout.VERTICAL);
                            holder.l[id].setBackground(context.getDrawable(customborder));
                            holder.lyocomanda.addView(holder.l[id]);
                        }

                    }

                    //FIN CUERPO PRINCIPAL DE EJECUCION

                } //EJECUCION DE DESCARTE DE FINAL DE CADENA
            } //EJECUCION DE DESCARTE DE BEBIDAS

        }

}

@Override
public int getItemCount() {

    return list_comandas.size();
}

public void removeItem(int position) {
    list_comandas.remove(position);
    notifyItemRemoved(position);
}

@Override
public void onClick(View view) {
    if (listener != null)
    {
        listener.onClick(view);
    }
}

public void setOnClickListener(View.OnClickListener listener)
{
    this.listener = listener;
}

public class ComandaAdapterViewHolder extends RecyclerView.ViewHolder {

    TextView txt_comanda, txt_mesa;
    private LinearLayout lyocomanda;

    private Integer cant_platos =500;

    private TextView[] t = new TextView[(cant_platos*8)];
    private LinearLayout[] l = new LinearLayout[cant_platos];
    private Button[] b = new Button[cant_platos];

    public ComandaAdapterViewHolder(View itemView) {
        super(itemView);

        // Inicializamos los controles
        lyocomanda = (LinearLayout) itemView.findViewById(R.id.lyocomanda);

        txt_comanda = (TextView) itemView.findViewById(R.id.txt_comanda);

        txt_mesa = (TextView) itemView.findViewById(R.id.txt_mesa);

            for (int i = 0; i <cant_platos; i++) {

                /////////////////////////////CONFIGURACION DEL BOTON///////////////////////////

                b[i] = new Button(itemView.getContext());
                b[i].setOnClickListener(listener);

                ///////////////////////////CONFIGURACION DEL CONTORNO///////////////////////////

                l[i] = new LinearLayout(itemView.getContext());
                t[i] = new TextView(itemView.getContext());

            }

          }
       }

      }

这是活动

public class MainActivity extends AppCompatActivity {


private ComandaAdapter mComandaAdapter;
ArrayList<Comanda> lista_Comanda;
RecyclerView rec_Lista;

public int counter = 0;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    rec_Lista = (RecyclerView) findViewById(R.id.rec_lista);

    new CountDownTimer(10000, 100){

        @Override
        public void onTick(long millisUntilFinished) {


            counter++;

        }

        @Override
        public void onFinish() {
            try{
               loadRetrofitComanda();
                counter = 0;
                start();
            }
            catch (Exception e){
                mostrarMensaje("Error: " + e.getMessage());
            }

        }
    }.start();

}

@Override
protected void onResume() {
    super.onResume();

    loadRetrofitComanda();

}


private void loadRetrofitComanda()
{
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://192.168.0.20:3000")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    IRequestComanda request = retrofit.create(IRequestComanda.class);

    Call<ArrayList<Comanda>> call = request.getJSONComandas();

    call.enqueue(new Callback<ArrayList<Comanda>>() {
        @Override
        public void onResponse(Call<ArrayList<Comanda>> call, Response<ArrayList<Comanda>> response) {

            ArrayList<Comanda> lista = response.body();

            lista_Comanda = lista;

            // Refresh recyclerview
           setAdapter();
            configurarOrientacionLayout();
        }

        @Override
        public void onFailure(Call<ArrayList<Comanda>> call, Throwable t) {

            mostrarMensaje("Error: " + t.getMessage());
        }
    });
}




private void mostrarMensaje(String mensaje)
{
    Toast.makeText(getApplicationContext(), mensaje, Toast.LENGTH_SHORT).show();
}


private void setAdapter()
{
    mComandaAdapter = new ComandaAdapter(getApplicationContext(), lista_Comanda);

    mComandaAdapter.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mostrarMensaje("ejecutar accion");
        }
    });

    rec_Lista.setAdapter(mComandaAdapter);



}


private void configurarOrientacionLayout()
{
    rec_Lista.setLayoutManager(new       L   LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false));
     }
  }

2 个答案:

答案 0 :(得分:0)

稍微更新一下,当新数据以2行代码到达时,我已设法保持recyclelerview状态:

     recyclerViewState = rec_Lista.getLayoutManager().onSaveInstanceState();//save
     setAdapter();
     configurarOrientacionLayout();
     rec_Lista.getLayoutManager().onRestoreInstanceState(recyclerViewState);//restore

通过保存和恢复布局管理器befor并在调用setAdapter方法之后,还有1个问题要去...每个回收器项目的滚动位置。

解决了最后的问题。

mComandaAdapter.notifyItemInserted(lista_Comanda.size());

所以我检查新物品是否已经到达,如果是这样,我只是将物品隔离并将其添加到回收器中,其他一切保持不变。我不是每次新数据到达时都设置适配器。

希望这可以帮助任何人。

答案 1 :(得分:0)

在使用ListAdapter时,RecyclerView即开即用,而后者又使用DiffUtil。然后,您只需通过submitList(newList)通知适配器新列表。

DiffUtil提取一个旧列表和一个新列表,并找出不同之处。它查找添加,删除或更改了哪些项目,RecyclerView可以使用该信息来更新这些项目,这比重做整个列表要有效得多。

RecyclerView负责将其平稳地呈现给用户。