SwipeRefreshLayout 后数据重复

Data duplication after SwipeRefreshLayout

我在我的 Activity 中添加了一个 SwipeRefreshLayout 以在需要时更新 table,但我遇到了以下问题。当我执行 Swipe 时,出于某种原因,table 被复制了。这是我的 xml:

<LinearLayout
    android:layout_marginTop="10dp"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/swipeRefresh"
        android:layout_gravity="center_horizontal"
        android:gravity="center_horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TableLayout
            android:layout_gravity="center_horizontal"
            android:gravity="center_horizontal"
            android:id="@+id/tabla"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </TableLayout>
    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>

所以我将它应用到我的 Activity:

public class ListaPreciosActivity extends AppCompatActivity {
    private SwipeRefreshLayout recarga;

    @Override
protected void onCreate(Bundle savedInstanceState) { //onCreate dibuja los elementos
    super.onCreate(savedInstanceState);
    //getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
    setContentView(R.layout.activity_lista_precios);

    traerFecha(ListaPreciosActivity.this);
    fechaHoyMetodo();
    parsearFechasYValidar(ListaPreciosActivity.this);

    //botones
    carga = (Button)findViewById(R.id.btnCargarPrecio);
    cerrar = (Button)findViewById(R.id.btnCerrar);
    recarga = (SwipeRefreshLayout)findViewById(R.id.swipeRefresh);
    listaPreciosPapa();

    recarga.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    listaPreciosPapa();
                    recarga.setRefreshing(false);
                }
            }, 2000);
        }
    });

    //evento para cerrar sesión
    cerrar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            cerrarSesion(); //método
            new PreferenciaLogin(ListaPreciosActivity.this).guardarValor(0); //almacena el valor en la preferencia
            ListaPreciosActivity.this.finish();//cierra la actividad
        }
    });

    //evento para cargar precio
    carga.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //método para cargar precio
            cargarPrecio();
        }
    });
}

    private void listaPreciosPapa() {//método que nos trae los precios
    //stringrquest para traer los datos del php
    //lo ideal sería parsear el array
    recarga.setRefreshing(true);
    StringRequest stringRequest = new StringRequest(Request.Method.POST, "url",
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Tabla tabla = new Tabla(ListaPreciosActivity.this, (TableLayout)findViewById(R.id.tabla));
                    tabla.agregarCabecera(R.array.cabecera_tabla);
                    try {//try para atrapar errores si es que los hay
                        JSONArray jsonArray = new JSONArray(response);//creamos un array que dibuja los datos del php
                        for (int i = 0; i < jsonArray.length(); i++) {//ciclo para ya saben qué
                            JSONObject jsonObject1 = jsonArray.getJSONObject(i);//creamos un JSON objeto
                            //le agregamos los campos pertinentes, requisito funciona: nombre de los campos de la bd
                            String zona = jsonObject1.getString("nombreZona");
                            String premin = jsonObject1.getString("precioMinimo");
                            String premax = jsonObject1.getString("precioMaximo");
                            String prom = jsonObject1.getString("promedio");

                            //probando la tabla

                            ArrayList<String> elementos = new ArrayList<String>();
                            zona = zona.replaceAll(" ", "\n");
                            elementos.add(zona);
                            elementos.add(premax);
                            elementos.add(premin);
                            elementos.add(prom);

                            tabla.agregarFilaTabla(elementos);

                            recarga.setRefreshing(false);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();//captamos el error
                        recarga.setRefreshing(false);
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
            recarga.setRefreshing(false);
        }
    });//same bug, different error
    RequestQueue requestQueue = Volley.newRequestQueue(ListaPreciosActivity.this); //esto ya fue explicado
    requestQueue.add(stringRequest);
}

Tabla class:

public class Tabla {
    // Variables de la clase

    private TableLayout tabla;          // Layout donde se pintará la tabla
    private ArrayList<TableRow> filas;  // Array de las filas de la tabla
    private Activity actividad;
    private Resources rs;
    private int FILAS, COLUMNAS;        // Filas y columnas de nuestra tabla

    /**
     * Constructor de la tabla
     * @param actividad Actividad donde va a estar la tabla
     * @param tabla TableLayout donde se pintará la tabla
     */
    public Tabla(Activity actividad, TableLayout tabla)
    {
        this.actividad = actividad;
        this.tabla = tabla;
        rs = this.actividad.getResources();
        FILAS = COLUMNAS = 0;
        filas = new ArrayList<TableRow>();
    }

    /**
     * Añade la cabecera a la tabla
     * @param recursocabecera Recurso (array) donde se encuentra la cabecera de la tabla
     */
    public void agregarCabecera(int recursocabecera)
    {
        TableRow.LayoutParams layoutCelda;
        TableRow fila = new TableRow(actividad);
        TableRow.LayoutParams layoutFila = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT);
        fila.setLayoutParams(layoutFila);

        String[] arraycabecera = rs.getStringArray(recursocabecera);
        COLUMNAS = arraycabecera.length;

        for(int i = 0; i < arraycabecera.length; i++)
        {
            TextView texto = new TextView(actividad);
            layoutCelda = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, 100);
            texto.setText(arraycabecera[i]);
            texto.setGravity(Gravity.CENTER_HORIZONTAL);
            texto.setTextAppearance(actividad, R.style.estilo_celda);
            texto.setBackgroundResource(R.drawable.tabla_celda_cabecera);
            texto.setLayoutParams(layoutCelda);
            fila.addView(texto);
        }
        tabla.addView(fila);
        filas.add(fila);
        FILAS++;
    }

    /**
     * Agrega una fila a la tabla
     * @param elementos Elementos de la fila
     */
    public void agregarFilaTabla(ArrayList<String> elementos)
    {
        TableRow.LayoutParams layoutCelda;
        TableRow.LayoutParams layoutFila = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        TableRow fila = new TableRow(actividad);
        fila.setLayoutParams(layoutFila);

        for(int i = 0; i< elementos.size(); i++)
        {
            TextView texto = new TextView(actividad);
            texto.setText(String.valueOf(elementos.get(i)));
            texto.setGravity(Gravity.CENTER);
            texto.setTextAppearance(actividad, R.style.estilo_celda);
            texto.setBackgroundResource(R.drawable.tabla_celda);
            layoutCelda = new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.MATCH_PARENT);
            texto.setLayoutParams(layoutCelda);
            fila.addView(texto);
        }
        tabla.addView(fila);
        filas.add(fila);
        FILAS++;
    }

    /**
     * Elimina una fila de la tabla
     * @param indicefilaeliminar Indice de la fila a eliminar
     */
    public void eliminarFila(int indicefilaeliminar)
    {
        if( indicefilaeliminar > 0 && indicefilaeliminar < FILAS )
        {
            tabla.removeViewAt(indicefilaeliminar);
            FILAS--;
        }
    }

    /**
     * Devuelve las filas de la tabla, la cabecera se cuenta como fila
     * @return Filas totales de la tabla
     */
    public int getFilas()
    {
        return FILAS;
    }

    /**
     * Devuelve las columnas de la tabla
     * @return Columnas totales de la tabla
     */
    public int getColumnas()
    {
        return COLUMNAS;
    }

    /**
     * Devuelve el número de celdas de la tabla, la cabecera se cuenta como fila
     * @return Número de celdas totales de la tabla
     */
    public int getCeldasTotales()
    {
        return FILAS * COLUMNAS;
    }

    /**
     * Obtiene el ancho en píxeles de un texto en un String
     * @param texto Texto
     * @return Ancho en píxeles del texto
     */
    private int obtenerAnchoPixelesTexto(String texto)
    {
        Paint p = new Paint();
        Rect bounds = new Rect();
        p.setTextSize(50);

        p.getTextBounds(texto, 0, texto.length(), bounds);
        return bounds.width();
    }
}

没有滑动的演示:

enter image description here

滑动后演示:

enter image description here

有人知道我做错了什么吗?

如果我理解正确你的问题,

您正在调用此方法两次 listaPreciosPapa();。一个来自 onCreate() 和一个来自 swipe refresh listener.

的回调

listaPreciosPapa 中,您正在创建 Tabla class 的实例,您正在传递 activity & TableLayout 的实例。

在 Tabla class 的构造函数中,您正在存储 activity 实例、TableLayout 实例,并创建 filas 列表的新实例。

因为 Activity & Table初始化时两次布局实例相同 Table class.

Tabla tabla = new Tabla(ListaPreciosActivity.this, (TableLayout) findViewById(R.id.tabla));

所以发生了什么,它不断向同一个 tabla 添加新视图 TableLayout

第一次它将创建一个视图并添加到 table Table 布局 (tabla.addView(fila))。下次滑动刷新时,它会将新视图添加到相同的 table TableLatout (tabla.addView(fila))

您必须从 table 中删除旧数据而不是实施新数据

有个Whosebug question

myLinearLayout.someTableView.removeAllViews()

我认为你的代码应该是

tabla.removeAllViews()