diff --git a/AndroidProject/app/src/androidTest/java/es/unican/gasolineras/activities/main/FiltrarPorPrecioMaximoUITest.java b/AndroidProject/app/src/androidTest/java/es/unican/gasolineras/activities/main/FiltrarPorPrecioMaximoUITest.java new file mode 100644 index 0000000..ed0aa8d --- /dev/null +++ b/AndroidProject/app/src/androidTest/java/es/unican/gasolineras/activities/main/FiltrarPorPrecioMaximoUITest.java @@ -0,0 +1,97 @@ +package es.unican.gasolineras.activities.main; + +import static androidx.test.espresso.Espresso.onData; +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.action.ViewActions.typeText; +import static androidx.test.espresso.assertion.ViewAssertions.matches; +import static androidx.test.espresso.matcher.RootMatchers.isPlatformPopup; +import static androidx.test.espresso.matcher.ViewMatchers.withId; +import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.CoreMatchers.allOf; +import static org.hamcrest.CoreMatchers.anything; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static es.unican.gasolineras.utils.MockRepositories.getTestRepository; + +import android.content.Context; + +import androidx.test.espresso.DataInteraction; +import androidx.test.ext.junit.rules.ActivityScenarioRule; +import androidx.test.platform.app.InstrumentationRegistry; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import dagger.hilt.android.testing.BindValue; +import dagger.hilt.android.testing.HiltAndroidRule; +import dagger.hilt.android.testing.HiltAndroidTest; +import dagger.hilt.android.testing.UninstallModules; +import es.unican.gasolineras.R; +import es.unican.gasolineras.injection.RepositoriesModule; +import es.unican.gasolineras.repository.IGasolinerasRepository; + +@UninstallModules(RepositoriesModule.class) +@HiltAndroidTest +public class FiltrarPorPrecioMaximoUITest { + @Rule(order = 0) // the Hilt rule must execute first + public HiltAndroidRule hiltRule = new HiltAndroidRule(this); + + @Rule(order = 1) + public ActivityScenarioRule activityRule = new ActivityScenarioRule<>(MainView.class); + + // I need the context to access resources, such as the json with test gas stations + final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + // Mock repository that provides data from a JSON file instead of downloading it from the internet. + @BindValue + public final IGasolinerasRepository repository = getTestRepository(context, R.raw.gasolineras_ccaa_06); + + + @Before + public void inicializa(){ + } + + @Test + public void testFiltarGasolinerasPorPrecioMaximoCasoExito() { + + //clicka en filtrar + onView(withId(R.id.menuFiltrar)).perform(click()); + + //clicka en el selector de combustible + onView(withId(R.id.spinnerCombustible)).perform(click()); + + //elige la opcion gasolina 95 E5 + onData(allOf(is(instanceOf(String.class)), + is("Gasoleo_A"))).inRoot(isPlatformPopup()).perform(click()); + + //clicka en el campo de precio máximo + onView(withId(R.id.etPrecioMax)).perform(click()); + + //escribe 1.512 en el campo de precio máximo + onView(withId(R.id.etPrecioMax)).perform(typeText("1.4")); + + //clicka el boton filtrar + onView(withId(R.id.btnFiltrar)).perform(click()); + + //comprueba la direccion de la primera gasolinera + DataInteraction g1 = onData(anything()).inAdapterView(withId(R.id.lvStations)).atPosition(0); + g1.onChildView(withId(R.id.tvAddress)).check(matches(withText("CALLE GUTIERREZ SOLANA 24, 24"))); + + //comprueba la direccion de la segunda gasolinera + DataInteraction g2 = onData(anything()).inAdapterView(withId(R.id.lvStations)).atPosition(1); + g2.onChildView(withId(R.id.tvAddress)).check(matches(withText("P.I. CROS km CENTRO COMERCIAL M"))); + } + + @Test + public void testFiltrarGasolinerasPorPrecioMaximoError(){ + + //clicka en filtrar + onView(withId(R.id.menuFiltrar)).perform(click()); + + //comprueba mensaje de error + onView(withId(R.id.tvListaVacia)). + check(matches(withText("Error: No hay ningun punto de interes añadido"))); + } +} diff --git a/AndroidProject/app/src/androidTest/java/es/unican/gasolineras/activities/main/OrdenarGasolineraCercanasUITest.java b/AndroidProject/app/src/androidTest/java/es/unican/gasolineras/activities/main/OrdenarGasolineraCercanasUITest.java index e1339bc..7712d29 100644 --- a/AndroidProject/app/src/androidTest/java/es/unican/gasolineras/activities/main/OrdenarGasolineraCercanasUITest.java +++ b/AndroidProject/app/src/androidTest/java/es/unican/gasolineras/activities/main/OrdenarGasolineraCercanasUITest.java @@ -87,7 +87,7 @@ public void testOrdenaGasolinerasCercanasCasoExito() { onView(withId(R.id.buttonGuardar)).perform(click()); //clicka en filtrar - onView(withId(R.id.menuFiltrar)).perform(click()); + onView(withId(R.id.menuOrdenar)).perform(click()); //clicka en el selector de Pto Interes onView(withId(R.id.spinnerPtosInteres)).perform(click()); @@ -112,7 +112,7 @@ public void testOrdenaGasolinerasCercanasCasoExito() { public void OrdenarGasolinerasCercanasNoPtoInteres(){ //clicka en filtrar - onView(withId(R.id.menuFiltrar)).perform(click()); + onView(withId(R.id.menuOrdenar)).perform(click()); //comprueba mensaje de error onView(withId(R.id.tvListaVacia)). diff --git a/AndroidProject/app/src/main/java/es/unican/gasolineras/activities/main/IMainContract.java b/AndroidProject/app/src/main/java/es/unican/gasolineras/activities/main/IMainContract.java index 08f5bea..37bcd89 100644 --- a/AndroidProject/app/src/main/java/es/unican/gasolineras/activities/main/IMainContract.java +++ b/AndroidProject/app/src/main/java/es/unican/gasolineras/activities/main/IMainContract.java @@ -4,8 +4,8 @@ import es.unican.gasolineras.model.Gasolinera; import es.unican.gasolineras.model.PuntoInteres; +import es.unican.gasolineras.model.TipoCombustible; import es.unican.gasolineras.repository.IGasolinerasRepository; -import es.unican.gasolineras.repository.IPuntosInteresDAO; /** * The Presenter-View contract for the Main activity. @@ -40,7 +40,7 @@ public interface Presenter { public void onMenuInfoClicked(); /** - * + * The presenter is informed that the Filtrar item in the menu has been clicked */ public void onMenuAnhadirPuntoInteresClicked(); } @@ -112,14 +112,28 @@ public interface View { /** * La vista manda una peticion al presenter para que muestre el - * popup de filtrar. + * popup de ordenar. */ - public void showPopUpFiltrar(); + public void showPopUpOrdenar(); /** * Informa al presenter que el boton de ordenar ha sido clickado. */ public void onOrdenarClicked(PuntoInteres p); + + + + /** + * Informa al presenter que el boton de filtrar ha sido clickado. + */ public void showAnhadirPuntoInteresActivity(); + + public void onFiltrarClicked(double precioMax, TipoCombustible combustible); + + /** + * La vista manda una peticion al presenter para que muestre el + * popup de filtrar. + */ + public void showPopUpFiltar(); } } diff --git a/AndroidProject/app/src/main/java/es/unican/gasolineras/activities/main/MainPresenter.java b/AndroidProject/app/src/main/java/es/unican/gasolineras/activities/main/MainPresenter.java index c1cd616..5137a3c 100644 --- a/AndroidProject/app/src/main/java/es/unican/gasolineras/activities/main/MainPresenter.java +++ b/AndroidProject/app/src/main/java/es/unican/gasolineras/activities/main/MainPresenter.java @@ -6,6 +6,7 @@ import es.unican.gasolineras.model.Gasolinera; import es.unican.gasolineras.model.IDCCAAs; import es.unican.gasolineras.model.PuntoInteres; +import es.unican.gasolineras.model.TipoCombustible; import es.unican.gasolineras.repository.ICallBack; import es.unican.gasolineras.repository.IGasolinerasRepository; @@ -19,6 +20,14 @@ public class MainPresenter implements IMainContract.Presenter { /** Atributo lista gasolineras */ List gasolineras; + List gasolinerasMod; + + // Banderas para controlar el estado de ordenación y filtrado + private boolean estaOrdenada = false; + private boolean estaFiltrada = false; + + // Variables de estado para el último punto de interés de ordenación + private PuntoInteres puntoInteresOrdenActual = null; /** * @see IMainContract.Presenter#init(IMainContract.View) @@ -54,28 +63,38 @@ public void onMenuInfoClicked() { public void onMenuAnhadirPuntoInteresClicked() { view.showAnhadirPuntoInteresActivity(); } - - + /** + * Muestra el popup de ordenar + */ + public void onMenuOrdenarClicked() { + view.showPopUpOrdenar(); + } /** - * Loads the gas stations from the repository, and sends them to the view + * Muestra el popup de filtrar */ + public void onMenuFiltrarClicked() { + view.showPopUpFiltar(); + } + + + private void load() { IGasolinerasRepository repository = view.getGasolinerasRepository(); - ICallBack callBack = new ICallBack() { - @Override public void onSuccess(List stations) { gasolineras = stations; view.showStations(stations); view.showLoadCorrect(stations.size()); + gasolinerasMod = new ArrayList<>(gasolineras); + estaOrdenada = false; + estaFiltrada = false; } @Override public void onFailure(Throwable e) { view.showLoadError(); - view.showLoadError(); } }; view.getPuntosInteresDAO(); @@ -83,20 +102,40 @@ public void onFailure(Throwable e) { } /** - * Muestra el popup de filtrar + * Muestra la lista de gasolineras ordenadas por el punto de interes + * @param p el punto de interes */ - public void onMenuFiltrarClicked() { - view.showPopUpFiltrar(); + public void ordenarGasolinerasCercanasPtoInteres(PuntoInteres p) { + puntoInteresOrdenActual = p; + estaOrdenada = true; + gasolinerasMod.sort(new GasolineraDistanciaComparator(p)); + view.showStations(gasolinerasMod); } /** - * Muestra la lista de gasolineras ordenadas por el punto de interes - * @param p el punto de interes + * Filtra la lista de gasolineras por precio máximo y tipo de combustible. + * Aplica el filtro sobre la lista original y luego la ordena si estaba previamente ordenada. + * @param precioMax el precio máximo del combustible + * @param combustible el tipo de combustible */ - public void ordenarGasolinerasCercanasPtoInteres(PuntoInteres p) { - GasolineraDistanciaComparator comparator = new GasolineraDistanciaComparator(p); - List gasolinerasCopia = new ArrayList<>(gasolineras); - gasolinerasCopia.sort(comparator); - view.showStations(gasolinerasCopia); + public void filtraGasolinerasPorPrecioMaximo(double precioMax, TipoCombustible combustible) { + estaFiltrada = true; + + List gasolinerasFiltradas = new ArrayList<>(); + for (Gasolinera gasolinera : gasolineras) { + double precioCombustible = combustible.getPrecio(gasolinera); + if (precioCombustible > 0.0 && precioCombustible <= precioMax) { + gasolinerasFiltradas.add(gasolinera); + } + } + + // Si estaba ordenada, aplicar el orden sobre la lista filtrada + if (estaOrdenada) { + gasolinerasFiltradas.sort(new GasolineraDistanciaComparator(puntoInteresOrdenActual)); + } + + // Actualizar la lista modificada y mostrar + gasolinerasMod = gasolinerasFiltradas; + view.showStations(gasolinerasMod); } } diff --git a/AndroidProject/app/src/main/java/es/unican/gasolineras/activities/main/MainView.java b/AndroidProject/app/src/main/java/es/unican/gasolineras/activities/main/MainView.java index c33ae11..dd645a0 100644 --- a/AndroidProject/app/src/main/java/es/unican/gasolineras/activities/main/MainView.java +++ b/AndroidProject/app/src/main/java/es/unican/gasolineras/activities/main/MainView.java @@ -1,13 +1,17 @@ package es.unican.gasolineras.activities.main; import android.content.Intent; +import android.content.SharedPreferences; import android.os.Bundle; +import android.text.InputFilter; +import android.text.Spanned; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.ArrayAdapter; +import android.widget.EditText; import android.widget.ListView; import android.widget.Spinner; import android.widget.TextView; @@ -17,10 +21,10 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; -import androidx.room.Room; import org.parceler.Parcels; +import java.text.DecimalFormatSymbols; import java.util.List; import javax.inject.Inject; @@ -32,6 +36,7 @@ import es.unican.gasolineras.activities.puntoInteres.AnhadirPuntoInteresView; import es.unican.gasolineras.model.Gasolinera; import es.unican.gasolineras.model.PuntoInteres; +import es.unican.gasolineras.model.TipoCombustible; import es.unican.gasolineras.repository.AppDatabase; import es.unican.gasolineras.repository.DbFunctions; import es.unican.gasolineras.repository.IGasolinerasRepository; @@ -57,6 +62,7 @@ public class MainView extends AppCompatActivity implements IMainContract.View { @Inject IGasolinerasRepository repository; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -99,15 +105,18 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { presenter.onMenuInfoClicked(); return true; } - if (itemId == R.id.menuFiltrar) { - presenter.onMenuFiltrarClicked(); + if (itemId == R.id.menuOrdenar) { + presenter.onMenuOrdenarClicked(); return true; } - if (itemId == R.id.menuItemAnhadirPuntoInteres) { presenter.onMenuAnhadirPuntoInteresClicked(); return true; } + if (itemId == R.id.menuFiltrar) { + presenter.onMenuFiltrarClicked(); + return true; + } return super.onOptionsItemSelected(item); } @@ -193,16 +202,16 @@ public void getPuntosInteresDAO() { } @Override - public void showPopUpFiltrar() { + public void showPopUpOrdenar() { final AlertDialog.Builder builder = new AlertDialog.Builder(MainView.this); LayoutInflater inflater = MainView.this.getLayoutInflater(); View dialogView = inflater.inflate(R.layout.puntos_interes_dialog_layout, null); // Referencio el spinner Spinner spinner = dialogView.findViewById(R.id.spinnerPtosInteres); - TextView tvListaVacia = dialogView.findViewById(R.id.tvListaVacia); // Referencia al TextView para el mensaje de lista vacía - View btnOrdenar = dialogView.findViewById(R.id.btnOrdenar); // Referencia al botón "Ordenar" - View btnCancelar = dialogView.findViewById(R.id.btnCancelar); // Referencia al botón "Cancelar" + TextView tvListaVacia = dialogView.findViewById(R.id.tvListaVacia); + View btnOrdenar = dialogView.findViewById(R.id.btnOrdenar); + View btnCancelar = dialogView.findViewById(R.id.btnCancelar); // Obtengo la lista de puntos de interés puntosInteres = puntosInteresDAO.getAll(); @@ -265,4 +274,118 @@ public void showAnhadirPuntoInteresActivity() { Intent intent = new Intent(this, AnhadirPuntoInteresView.class); startActivity(intent); } + + @Override + public void onFiltrarClicked(double precioMax, TipoCombustible combustible) { + presenter.filtraGasolinerasPorPrecioMaximo(precioMax, combustible); + } + + @Override + public void showPopUpFiltar() { + final AlertDialog.Builder builder = new AlertDialog.Builder(MainView.this); + LayoutInflater inflater = MainView.this.getLayoutInflater(); + View dialogView = inflater.inflate(R.layout.filtrar_precio_max_dialog_layout, null); + + // Referencio el spinner + Spinner spinner = dialogView.findViewById(R.id.spinnerCombustible); + EditText etPrecioMax = dialogView.findViewById(R.id.etPrecioMax); + + // Nuevo filtro mejorado para controlar decimales + etPrecioMax.setFilters(new InputFilter[]{new InputFilter() { + DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(); + + @Override + public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { + String resultingText = dest.subSequence(0, dstart) + + source.toString() + + dest.subSequence(dend, dest.length()); + + int decimalIndex = resultingText.indexOf(decimalFormatSymbols.getDecimalSeparator()); + + // Si no hay punto decimal, permitir la entrada + if (decimalIndex == -1) { + return source; + } + + // Verificar cuántos decimales habría después del punto + String decimals = resultingText.substring(decimalIndex + 1); + if (decimals.length() > 3) { + return ""; // Bloquear la entrada si excedería 2 decimales + } + + return source; + } + }}); + + View btnFiltrar = dialogView.findViewById(R.id.btnFiltrar); + View btnCancelar = dialogView.findViewById(R.id.btnCancelar); + + // Llenar el spinner con los valores del enum TipoCombustible + ArrayAdapter adapter = new ArrayAdapter<>( + MainView.this, + android.R.layout.simple_spinner_item, + TipoCombustible.values() + ); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinner.setAdapter(adapter); + + // Recuperar SharedPreferences para obtener el último combustible y precio + SharedPreferences sharedPreferences = getSharedPreferences("AppPreferences", MODE_PRIVATE); + String lastSelectedFuelType = sharedPreferences.getString("lastFuelType", null); + String lastMaxPriceTxt = sharedPreferences.getString("lastMaxPrice", "-1"); + double lastMaxPrice = Double.parseDouble(lastMaxPriceTxt); + + // Establecer el valor del EditText y el Spinner si hay preferencias guardadas + if (lastSelectedFuelType != null) { + int spinnerPosition = adapter.getPosition(TipoCombustible.valueOf(lastSelectedFuelType)); + spinner.setSelection(spinnerPosition); + } + if (lastMaxPrice != -1) { + etPrecioMax.setText(String.valueOf(lastMaxPrice)); + } + + // Creo el alert y muestro el dialog + builder.setView(dialogView); + AlertDialog dialog = builder.create(); + dialog.show(); + + // Listener para el botón "Cancelar" + btnCancelar.setOnClickListener(v -> dialog.dismiss()); + + // Listener para el botón "Filtrar" + btnFiltrar.setOnClickListener(v -> { + String maxPriceText = etPrecioMax.getText().toString(); + + if (maxPriceText.isEmpty()) { + Toast.makeText(MainView.this, "Por favor, introduce un precio máximo.", Toast.LENGTH_SHORT).show(); + } else { + try { + // Convertir el texto ingresado a un número y verificar si es positivo + double precioMax = Double.parseDouble(maxPriceText); + + if (precioMax < 0) { + Toast.makeText(MainView.this, "El precio máximo debe ser un número positivo.", Toast.LENGTH_SHORT).show(); + } else { + // Obtener el tipo de combustible seleccionado del spinner + TipoCombustible combustible = (TipoCombustible) spinner.getSelectedItem(); + + // Guardar el último combustible seleccionado y el precio máximo en SharedPreferences + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString("lastFuelType", combustible.name()); + editor.putString("lastMaxPrice", maxPriceText); + editor.apply(); + + // Llamar al método onFiltrarClicked pasando el tipo de combustible y el precio máximo + onFiltrarClicked(precioMax, combustible); + + // Cerrar el popup + dialog.dismiss(); + } + } catch (NumberFormatException e) { + // Mostrar mensaje si el valor no es un número válido + Toast.makeText(MainView.this, "Por favor, introduce un número válido para el precio máximo.", Toast.LENGTH_SHORT).show(); + } + } + }); + } } \ No newline at end of file diff --git a/AndroidProject/app/src/main/java/es/unican/gasolineras/model/Gasolinera.java b/AndroidProject/app/src/main/java/es/unican/gasolineras/model/Gasolinera.java index a758a84..9a1f1d4 100644 --- a/AndroidProject/app/src/main/java/es/unican/gasolineras/model/Gasolinera.java +++ b/AndroidProject/app/src/main/java/es/unican/gasolineras/model/Gasolinera.java @@ -29,8 +29,20 @@ public class Gasolinera { @SerializedName("Dirección") protected String direccion; @SerializedName("Municipio") protected String municipio; + @SerializedName("Precio Biodiesel") protected double biodiesel; + @SerializedName("Precio Bioetanol") protected double bioetanol; + @SerializedName("Precio Gas Natural Comprimido") protected double gnc; + @SerializedName("Precio Gas Natural Licuado") protected double gnl; + @SerializedName("Precio Gases licuados del petróleo") protected double glp; @SerializedName("Precio Gasoleo A") protected double gasoleoA; + @SerializedName("Precio Gasoleo B") protected double gasoleoB; + @SerializedName("Precio Gasoleo Premium") protected double gasoleoPremium; + @SerializedName("Precio Gasolina 95 E10") protected double gasolina95E10; @SerializedName("Precio Gasolina 95 E5") protected double gasolina95E5; + @SerializedName("Precio Gasolina 95 E5 Premium") protected double gasolina95E5Premium; + @SerializedName("Precio Gasolina 98 E10") protected double gasolina98E10; + @SerializedName("Precio Gasolina 98 E5") protected double gasolina98E5; + @SerializedName("Precio Hidrogeno") protected double hidrogeno; @SerializedName("Horario") protected String horario; diff --git a/AndroidProject/app/src/main/java/es/unican/gasolineras/model/TipoCombustible.java b/AndroidProject/app/src/main/java/es/unican/gasolineras/model/TipoCombustible.java new file mode 100644 index 0000000..6836f66 --- /dev/null +++ b/AndroidProject/app/src/main/java/es/unican/gasolineras/model/TipoCombustible.java @@ -0,0 +1,58 @@ +package es.unican.gasolineras.model; + +import static java.sql.Types.NULL; + +import org.w3c.dom.NamedNodeMap; + +public enum TipoCombustible { + BIODIESEL, + BIOETANOL, + GNC, + GNL, + GLP, + GASOLEO_A, + GASOLEO_B, + GASOLEO_PREMIUM, + GASOLINA_95_E10, + GASOLINA_95_E5, + GASOLINA_95_E5_PREMIUM, + GASOLINA_98_E10, + GASOLINA_98_E5, + HIDROGENO; + + public double getPrecio(Gasolinera gasolinera) { + switch (this) { + case BIODIESEL: return gasolinera.getBiodiesel(); + case BIOETANOL: return gasolinera.getBioetanol(); + case GNC: return gasolinera.getGnc(); + case GNL: return gasolinera.getGnl(); + case GLP: return gasolinera.getGlp(); + case GASOLEO_A: return gasolinera.getGasoleoA(); + case GASOLEO_B: return gasolinera.getGasoleoB(); + case GASOLEO_PREMIUM: return gasolinera.getGasolina95E5(); + case GASOLINA_95_E10: return gasolinera.getGasolina95E10(); + case GASOLINA_95_E5: return gasolinera.getGasolina95E5(); + case GASOLINA_95_E5_PREMIUM: return gasolinera.getGasolina95E5Premium(); + case GASOLINA_98_E10: return gasolinera.getGasolina98E10(); + case GASOLINA_98_E5: return gasolinera.getGasolina98E5(); + case HIDROGENO: return gasolinera.getHidrogeno(); + } + return 0; + } + + @Override + public String toString() { + // Reemplaza "_" con espacios y convierte cada palabra a mayúscula inicial + String name = name().toLowerCase().replace('_', ' '); + String[] words = name.split(" "); + StringBuilder formattedName = new StringBuilder(); + for (String word : words) { + formattedName.append(Character.toUpperCase(word.charAt(0))) + .append(word.substring(1)) + .append(" "); + } + return formattedName.toString().trim(); + } +} + + diff --git a/AndroidProject/app/src/main/res/drawable/filter.png b/AndroidProject/app/src/main/res/drawable/filter.png new file mode 100644 index 0000000..10ebc60 Binary files /dev/null and b/AndroidProject/app/src/main/res/drawable/filter.png differ diff --git a/AndroidProject/app/src/main/res/drawable/filtro.png b/AndroidProject/app/src/main/res/drawable/ordenar.png similarity index 100% rename from AndroidProject/app/src/main/res/drawable/filtro.png rename to AndroidProject/app/src/main/res/drawable/ordenar.png diff --git a/AndroidProject/app/src/main/res/layout/filtrar_precio_max_dialog_layout.xml b/AndroidProject/app/src/main/res/layout/filtrar_precio_max_dialog_layout.xml new file mode 100644 index 0000000..c4981a4 --- /dev/null +++ b/AndroidProject/app/src/main/res/layout/filtrar_precio_max_dialog_layout.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + +