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()
我在我的 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()