Estructura principal de la app
This commit is contained in:
parent
937bd305e6
commit
d96858d3c2
147
README.md
147
README.md
|
|
@ -1,109 +1,104 @@
|
|||
|
||||
# El Faro del Peregrino
|
||||
Una aplicación espiritual para acompañar el camino interior y comunitario.
|
||||
|
||||
El Faro del Peregrino es una aplicación diseñada para ofrecer luz, guía y herramientas prácticas a quienes desean profundizar en su vida espiritual. Su propósito es integrar oración, reflexión, comunidad y belleza visual en una experiencia sencilla y significativa.
|
||||
Una aplicación para acompañar el camino interior y comunitario, integrando oración, reflexión y comunidad en una experiencia visualmente inspiradora.
|
||||
|
||||
---
|
||||
|
||||
## Objetivos del proyecto
|
||||
- Crear una app que acompañe el crecimiento espiritual personal.
|
||||
- Integrar recursos como oraciones, meditaciones, lecturas y seguimiento del camino interior.
|
||||
- Diseñar una interfaz cálida, estética y accesible.
|
||||
- Construir una base sólida para futuras funcionalidades como:
|
||||
- Comunidad de peregrinos
|
||||
- Diario espiritual
|
||||
- Ritmos diarios (Laudes, Vísperas, etc.)
|
||||
- Notificaciones de oración
|
||||
- Contenidos multimedia
|
||||
## ✨ Propósito
|
||||
|
||||
El Faro del Peregrino nace para ofrecer luz, guía y herramientas prácticas a quienes desean profundizar en su vida espiritual. Busca integrar recursos de oración, reflexión y comunidad en una app sencilla, cálida y significativa.
|
||||
|
||||
---
|
||||
|
||||
## Tecnologías utilizadas
|
||||
Este proyecto está construido con:
|
||||
## 🎯 Objetivos
|
||||
|
||||
- Java / Kotlin (según evolucione el código del módulo app/)
|
||||
- Gradle como sistema de construcción
|
||||
- Android Studio como entorno de desarrollo
|
||||
- Estructura modular preparada para escalar
|
||||
- Acompañar el crecimiento espiritual personal y comunitario.
|
||||
- Integrar oraciones, meditaciones, lecturas y seguimiento del camino interior.
|
||||
- Ofrecer una interfaz estética, accesible y acogedora.
|
||||
- Sentar las bases para futuras funcionalidades:
|
||||
- Comunidad de peregrinos
|
||||
- Diario espiritual
|
||||
- Ritmos diarios (Laudes, Vísperas, etc.)
|
||||
- Notificaciones de oración
|
||||
- Contenidos multimedia
|
||||
|
||||
---
|
||||
|
||||
## Estructura del repositorio
|
||||
`
|
||||
## 🛠️ Tecnologías
|
||||
|
||||
- **Lenguajes:** Java / Kotlin (según evolución del módulo `app/`)
|
||||
- **Build:** Gradle (con wrapper incluido)
|
||||
- **IDE:** Android Studio (recomendado Flamingo o superior)
|
||||
- **Arquitectura:** Modular y escalable
|
||||
|
||||
---
|
||||
|
||||
## 📁 Estructura del repositorio
|
||||
|
||||
```
|
||||
el-faro-del-peregrino/
|
||||
│
|
||||
├── app/
|
||||
├── gradle/
|
||||
├── build.gradle.kts
|
||||
├── settings.gradle.kts
|
||||
├── gradle.properties
|
||||
└── .idea/
|
||||
`
|
||||
├── app/ # Código principal de la app
|
||||
├── gradle/ # Configuración de Gradle
|
||||
├── build.gradle.kts # Build script raíz
|
||||
├── settings.gradle.kts # Configuración de módulos
|
||||
├── gradle.properties # Propiedades globales
|
||||
└── .idea/ # Configuración de Android Studio
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cómo ejecutar el proyecto
|
||||
## 🚀 Cómo ejecutar el proyecto
|
||||
|
||||
1. Requisitos previos
|
||||
- Android Studio Flamingo o superior
|
||||
- JDK 17+
|
||||
- Gradle (incluido en el wrapper)
|
||||
1. **Requisitos previos**
|
||||
- Android Studio Flamingo o superior
|
||||
- JDK 17+
|
||||
- Gradle (incluido en el wrapper)
|
||||
|
||||
2. Clonar el repositorio
|
||||
`bash
|
||||
git clone https://git.tatvil.es/tatiana/el-faro-del-peregrino.git
|
||||
cd el-faro-del-peregrino
|
||||
`
|
||||
2. **Clonar el repositorio**
|
||||
```bash
|
||||
git clone https://git.tatvil.es/tatiana/el-faro-del-peregrino.git
|
||||
cd el-faro-del-peregrino
|
||||
```
|
||||
|
||||
3. Abrir en Android Studio
|
||||
- Selecciona Open
|
||||
- Elige la carpeta del proyecto
|
||||
- Android Studio descargará dependencias y sincronizará Gradle automáticamente
|
||||
3. **Abrir en Android Studio**
|
||||
- Selecciona *Open*
|
||||
- Elige la carpeta del proyecto
|
||||
- Android Studio descargará dependencias y sincronizará Gradle automáticamente
|
||||
|
||||
4. Ejecutar la app
|
||||
- Conecta un dispositivo o usa un emulador
|
||||
- Pulsa ▶️ Run
|
||||
4. **Ejecutar la app**
|
||||
- Conecta un dispositivo o usa un emulador
|
||||
- Pulsa ▶️ *Run*
|
||||
|
||||
---
|
||||
|
||||
🗺️ Roadmap inicial
|
||||
Este roadmap está alineado con el estilo profesional que ya usas en GitHub Issues.
|
||||
## 🗺️ Roadmap
|
||||
|
||||
Versión 0.1 — Estructura base
|
||||
- [ ] Configuración inicial del proyecto
|
||||
- [ ] Pantalla de bienvenida
|
||||
- [ ] Navegación básica
|
||||
**Versión 0.1 — Estructura base**
|
||||
- [ ] Configuración inicial del proyecto
|
||||
- [ ] Pantalla de bienvenida
|
||||
- [ ] Navegación básica
|
||||
- [ ] Tema visual inicial (colores, tipografías, iconografía)
|
||||
|
||||
Versión 0.2 — Contenidos espirituales
|
||||
- [ ] Módulo de oraciones
|
||||
- [ ] Lecturas del día
|
||||
- [ ] Modo oscuro contemplativo
|
||||
**Versión 0.2 — Contenidos espirituales**
|
||||
- [ ] Módulo de oraciones
|
||||
- [ ] Lecturas del día
|
||||
- [ ] Modo oscuro contemplativo
|
||||
|
||||
Versión 0.3 — Herramientas del peregrino
|
||||
- [ ] Diario espiritual
|
||||
- [ ] Seguimiento del camino
|
||||
- [ ] Notificaciones de ritmo diario
|
||||
**Versión 0.3 — Herramientas del peregrino**
|
||||
- [ ] Diario espiritual
|
||||
- [ ] Seguimiento del camino
|
||||
- [ ] Notificaciones de ritmo diario
|
||||
|
||||
Versión 1.0 — Comunidad
|
||||
- [ ] Perfil del peregrino
|
||||
- [ ] Espacios de oración compartida
|
||||
- [ ] Mensajes y peticiones
|
||||
**Versión 1.0 — Comunidad**
|
||||
- [ ] Perfil del peregrino
|
||||
- [ ] Espacios de oración compartida
|
||||
- [ ] Mensajes y peticiones
|
||||
|
||||
---
|
||||
|
||||
🤝 Contribuciones
|
||||
Este proyecto está en desarrollo activo.
|
||||
Las ideas, mejoras y bugs se gestionan mediante GitHub Issues siguiendo un flujo profesional.
|
||||
## 🌅 Inspiración
|
||||
|
||||
---
|
||||
> “El faro no navega por ti, pero ilumina el camino.”
|
||||
|
||||
📜 Licencia
|
||||
Pendiente de definir.
|
||||
Recomendación: MIT o Apache 2.0 para proyectos abiertos; licencia privada si será app personal o comercial.
|
||||
|
||||
---
|
||||
|
||||
🕯️ Inspiración
|
||||
> “El faro no navega por ti, pero ilumina el camino.”
|
||||
Este proyecto nace para ofrecer luz, calma y dirección en medio del viaje interior.
|
||||
Este proyecto busca ofrecer luz, calma y dirección en el viaje interior.
|
||||
|
|
|
|||
|
|
@ -46,5 +46,6 @@ dependencies {
|
|||
implementation("com.google.android.gms:play-services-location:21.3.0")
|
||||
implementation(libs.volley)
|
||||
implementation(libs.glide)
|
||||
implementation(libs.mpandroidchart)
|
||||
annotationProcessor(libs.glide.compiler)
|
||||
}
|
||||
|
|
@ -7,6 +7,13 @@
|
|||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<queries>
|
||||
<package android:name="com.google.android.apps.maps" />
|
||||
<intent>
|
||||
<action android:name="android.intent.action.DIAL" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
|
|
@ -31,6 +38,16 @@
|
|||
android:label="Detalle de la Etapa"
|
||||
android:parentActivityName=".MainActivity">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".EtapasActivity"
|
||||
android:label="Etapas del Camino"
|
||||
android:parentActivityName=".MainActivity">
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".DetalleServicioActivity"
|
||||
android:label="Detalle del Servicio"
|
||||
android:parentActivityName=".DetalleEtapaActivity">
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package es.tatvil.elfarodelperegrino;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
|
@ -40,6 +41,12 @@ public class AlbergueAdapter extends RecyclerView.Adapter<AlbergueAdapter.Alberg
|
|||
float distanciaKm = results[0] / 1000;
|
||||
|
||||
holder.tvDistancia.setText(String.format(Locale.getDefault(), "A %.1f km del destino", distanciaKm));
|
||||
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(v.getContext(), DetalleServicioActivity.class);
|
||||
intent.putExtra("objeto", albergue);
|
||||
v.getContext().startActivity(intent);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
package es.tatvil.elfarodelperegrino;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
|
@ -17,12 +20,20 @@ import com.android.volley.RequestQueue;
|
|||
import com.android.volley.toolbox.JsonObjectRequest;
|
||||
import com.android.volley.toolbox.Volley;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class DetalleEtapaActivity extends AppCompatActivity {
|
||||
|
||||
|
|
@ -39,24 +50,34 @@ public class DetalleEtapaActivity extends AppCompatActivity {
|
|||
ImageView ivImagen = findViewById(R.id.ivDetalleImagen);
|
||||
TextView tvTitulo = findViewById(R.id.tvDetalleTitulo);
|
||||
TextView tvDistancia = findViewById(R.id.tvDetalleDistancia);
|
||||
TextView tvDesnivelPos = findViewById(R.id.tvDetalleDesnivelPos);
|
||||
TextView tvDesnivelNeg = findViewById(R.id.tvDetalleDesnivelNeg);
|
||||
TextView tvHistoria = findViewById(R.id.tvDetalleHistoria);
|
||||
TextView tvReflexion = findViewById(R.id.tvDetalleReflexion);
|
||||
TextView tvClima = findViewById(R.id.tvDetalleClima);
|
||||
|
||||
tvTitulo.setText(etapa.getOrigen() + " - " + etapa.getDestino());
|
||||
tvDistancia.setText("Distancia: " + etapa.getDistancia() + " km");
|
||||
tvDistancia.setText(etapa.getDistancia() + " km");
|
||||
tvDesnivelPos.setText("+" + etapa.getDesnivelPositivo() + "m");
|
||||
tvDesnivelNeg.setText("-" + etapa.getDesnivelNegativo() + "m");
|
||||
tvHistoria.setText(etapa.getHitoHistorico());
|
||||
tvReflexion.setText(etapa.getReflexionEspiritual());
|
||||
|
||||
configurarGrafico(findViewById(R.id.elevationChart), etapa);
|
||||
|
||||
Glide.with(this)
|
||||
.load(etapa.getImagenUrl())
|
||||
.placeholder(android.R.drawable.ic_menu_gallery)
|
||||
.into(ivImagen);
|
||||
|
||||
obtenerClima(etapa.getLatitud(), etapa.getLongitud(), tvClima);
|
||||
obtenerClimaYPrevision(etapa.getLatitud(), etapa.getLongitud(), tvClima, findViewById(R.id.layoutForecast));
|
||||
|
||||
findViewById(R.id.btnVerClima).setOnClickListener(v ->
|
||||
obtenerClima(etapa.getLatitud(), etapa.getLongitud(), tvClima));
|
||||
// Botón Mapa
|
||||
findViewById(R.id.btnVerMapa).setOnClickListener(v -> {
|
||||
String uri = "geo:" + etapa.getLatitud() + "," + etapa.getLongitud() + "?q=" + etapa.getDestino();
|
||||
android.content.Intent intent = new android.content.Intent(android.content.Intent.ACTION_VIEW, android.net.Uri.parse(uri));
|
||||
startActivity(intent);
|
||||
});
|
||||
|
||||
// Botón Albergues
|
||||
findViewById(R.id.btnVerAlbergues).setOnClickListener(v -> {
|
||||
|
|
@ -76,7 +97,7 @@ public class DetalleEtapaActivity extends AppCompatActivity {
|
|||
if (cercanas.isEmpty()) {
|
||||
Toast.makeText(this, "No hay iglesias registradas cerca", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
mostrarDialogoSimple("Iglesias cercanas", cercanas);
|
||||
mostrarDialogoServicios("Iglesias cercanas", cercanas, etapa);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -92,7 +113,7 @@ public class DetalleEtapaActivity extends AppCompatActivity {
|
|||
if (cercanos.isEmpty()) {
|
||||
Toast.makeText(this, "No hay restaurantes registrados cerca", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
mostrarDialogoSimple("Restaurantes cercanos", cercanos);
|
||||
mostrarDialogoServicios("Restaurantes cercanos", cercanos, etapa);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -126,18 +147,17 @@ public class DetalleEtapaActivity extends AppCompatActivity {
|
|||
.show();
|
||||
}
|
||||
|
||||
private void mostrarDialogoSimple(String titulo, List<?> items) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Object item : items) {
|
||||
if (item instanceof Iglesia) sb.append("• ").append(((Iglesia) item).getNombre()).append("\n");
|
||||
if (item instanceof Restaurante) sb.append("• ").append(((Restaurante) item).getNombre()).append("\n");
|
||||
}
|
||||
private void mostrarDialogoServicios(String titulo, List<?> items, Etapa etapa) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
View view = LayoutInflater.from(this).inflate(R.layout.dialog_lista_albergues, null);
|
||||
RecyclerView rv = view.findViewById(R.id.rvDialogo);
|
||||
rv.setLayoutManager(new LinearLayoutManager(this));
|
||||
rv.setAdapter(new SimpleServicioAdapter(items, etapa.getLatitud(), etapa.getLongitud()));
|
||||
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle(titulo)
|
||||
.setMessage(sb.toString())
|
||||
.setPositiveButton("OK", null)
|
||||
.show();
|
||||
builder.setTitle(titulo)
|
||||
.setView(view)
|
||||
.setPositiveButton("Cerrar", null)
|
||||
.show();
|
||||
}
|
||||
|
||||
private double calcularDistancia(double lat1, double lon1, double lat2, double lon2) {
|
||||
|
|
@ -146,21 +166,100 @@ public class DetalleEtapaActivity extends AppCompatActivity {
|
|||
return results[0] / 1000; // Retorna km
|
||||
}
|
||||
|
||||
private void obtenerClima(double lat, double lon, TextView tvClima) {
|
||||
String url = "https://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + lon + "&appid=" + API_KEY + "&units=metric&lang=es";
|
||||
private void configurarGrafico(LineChart chart, Etapa etapa) {
|
||||
List<Entry> entries = new ArrayList<>();
|
||||
List<Integer> perfil = etapa.getPerfilElevacion();
|
||||
for (int i = 0; i < perfil.size(); i++) {
|
||||
entries.add(new Entry(i, perfil.get(i)));
|
||||
}
|
||||
|
||||
LineDataSet dataSet = new LineDataSet(entries, "Elevación (m)");
|
||||
dataSet.setColor(Color.parseColor("#4CAF50"));
|
||||
dataSet.setCircleColor(Color.parseColor("#4CAF50"));
|
||||
dataSet.setLineWidth(2f);
|
||||
dataSet.setCircleRadius(3f);
|
||||
dataSet.setDrawCircleHole(false);
|
||||
dataSet.setValueTextColor(Color.WHITE);
|
||||
dataSet.setDrawFilled(true);
|
||||
dataSet.setFillDrawable(getResources().getDrawable(R.drawable.ic_launcher_background)); // O un gradiente simple
|
||||
dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
|
||||
|
||||
LineData lineData = new LineData(dataSet);
|
||||
chart.setData(lineData);
|
||||
chart.getDescription().setEnabled(false);
|
||||
chart.getLegend().setTextColor(Color.WHITE);
|
||||
chart.getXAxis().setTextColor(Color.WHITE);
|
||||
chart.getAxisLeft().setTextColor(Color.WHITE);
|
||||
chart.getAxisRight().setEnabled(false);
|
||||
chart.animateX(1500);
|
||||
chart.invalidate();
|
||||
}
|
||||
|
||||
private void obtenerClimaYPrevision(double lat, double lon, TextView tvClima, LinearLayout layoutForecast) {
|
||||
// Clima actual
|
||||
String urlWeather = "https://api.openweathermap.org/data/2.5/weather?lat=" + lat + "&lon=" + lon + "&appid=" + API_KEY + "&units=metric&lang=es";
|
||||
// Previsión (5 días cada 3 horas)
|
||||
String urlForecast = "https://api.openweathermap.org/data/2.5/forecast?lat=" + lat + "&lon=" + lon + "&appid=" + API_KEY + "&units=metric&lang=es";
|
||||
|
||||
RequestQueue queue = Volley.newRequestQueue(this);
|
||||
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
|
||||
|
||||
// Request para clima actual
|
||||
JsonObjectRequest requestWeather = new JsonObjectRequest(Request.Method.GET, urlWeather, null,
|
||||
response -> {
|
||||
try {
|
||||
JSONObject main = response.getJSONObject("main");
|
||||
double temp = main.getDouble("temp");
|
||||
String desc = response.getJSONArray("weather").getJSONObject(0).getString("description");
|
||||
tvClima.setText("Clima actual: " + temp + "°C, " + desc);
|
||||
tvClima.setText("Hoy: " + temp + "°C, " + desc);
|
||||
} catch (JSONException e) {
|
||||
tvClima.setText("Error al procesar clima");
|
||||
tvClima.setText("Error en clima actual");
|
||||
}
|
||||
},
|
||||
error -> tvClima.setText("Error al obtener clima"));
|
||||
queue.add(request);
|
||||
}, error -> tvClima.setText("Error al conectar con clima"));
|
||||
|
||||
// Request para previsión
|
||||
JsonObjectRequest requestForecast = new JsonObjectRequest(Request.Method.GET, urlForecast, null,
|
||||
response -> {
|
||||
try {
|
||||
JSONArray list = response.getJSONArray("list");
|
||||
layoutForecast.removeAllViews();
|
||||
// Tomamos un punto por día (cada 8 registros son 24h aprox)
|
||||
for (int i = 8; i < list.length() && i <= 24; i += 8) {
|
||||
JSONObject dayObj = list.getJSONObject(i);
|
||||
double temp = dayObj.getJSONObject("main").getDouble("temp");
|
||||
String desc = dayObj.getJSONArray("weather").getJSONObject(0).getString("description");
|
||||
long dt = dayObj.getLong("dt") * 1000;
|
||||
String fecha = new SimpleDateFormat("EEE", new Locale("es", "ES")).format(new Date(dt));
|
||||
|
||||
agregarVistaPrevision(layoutForecast, fecha, temp, desc);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, error -> {});
|
||||
|
||||
queue.add(requestWeather);
|
||||
queue.add(requestForecast);
|
||||
}
|
||||
|
||||
private void agregarVistaPrevision(LinearLayout layout, String dia, double temp, String desc) {
|
||||
LinearLayout v = new LinearLayout(this);
|
||||
v.setOrientation(LinearLayout.VERTICAL);
|
||||
v.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f));
|
||||
v.setGravity(Gravity.CENTER);
|
||||
|
||||
TextView tvDia = new TextView(this);
|
||||
tvDia.setText(dia.toUpperCase());
|
||||
tvDia.setTextColor(Color.WHITE);
|
||||
tvDia.setTextSize(12);
|
||||
|
||||
TextView tvTemp = new TextView(this);
|
||||
tvTemp.setText((int)temp + "°");
|
||||
tvTemp.setTextColor(Color.parseColor("#FFEB3B"));
|
||||
tvTemp.setTextSize(16);
|
||||
tvTemp.setTypeface(null, android.graphics.Typeface.BOLD);
|
||||
|
||||
layout.addView(v);
|
||||
v.addView(tvDia);
|
||||
v.addView(tvTemp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
package es.tatvil.elfarodelperegrino;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
|
||||
public class DetalleServicioActivity extends AppCompatActivity {
|
||||
|
||||
private String nombre, telefono, tipo, descripcion;
|
||||
private double latitud, longitud;
|
||||
private boolean tieneCocina;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_detalle_servicio);
|
||||
|
||||
// Obtener datos del Intent
|
||||
Object object = getIntent().getSerializableExtra("objeto");
|
||||
|
||||
if (object instanceof Albergue) {
|
||||
Albergue a = (Albergue) object;
|
||||
nombre = a.getNombre();
|
||||
telefono = a.getTelefono();
|
||||
tipo = a.getTipo();
|
||||
descripcion = a.getComentario();
|
||||
latitud = a.getLatitud();
|
||||
longitud = a.getLongitud();
|
||||
tieneCocina = a.isTieneCocina();
|
||||
} else if (object instanceof Restaurante) {
|
||||
Restaurante r = (Restaurante) object;
|
||||
nombre = r.getNombre();
|
||||
telefono = ""; // Por ahora no hay en JSON
|
||||
tipo = getString(R.string.action_food).replace("\n", " ");
|
||||
descripcion = getString(R.string.msg_food_place);
|
||||
latitud = r.getLatitud();
|
||||
longitud = r.getLongitud();
|
||||
} else if (object instanceof Iglesia) {
|
||||
Iglesia i = (Iglesia) object;
|
||||
nombre = i.getNombre();
|
||||
telefono = "";
|
||||
tipo = getString(R.string.msg_interest_place); // Usando un string descriptivo como tipo
|
||||
descripcion = getString(R.string.msg_interest_place);
|
||||
latitud = i.getLatitud();
|
||||
longitud = i.getLongitud();
|
||||
}
|
||||
|
||||
// Vincular vistas
|
||||
TextView tvNombre = findViewById(R.id.tvDetalleNombre);
|
||||
TextView tvTipo = findViewById(R.id.tvDetalleTipo);
|
||||
TextView tvDescripcion = findViewById(R.id.tvDetalleDescripcion);
|
||||
TextView tvCocina = findViewById(R.id.tvDetalleCocina);
|
||||
View layoutExtras = findViewById(R.id.layoutExtras);
|
||||
MaterialButton btnLlamar = findViewById(R.id.btnLlamar);
|
||||
MaterialButton btnComoLlegar = findViewById(R.id.btnComoLlegar);
|
||||
|
||||
tvNombre.setText(nombre);
|
||||
tvTipo.setText(tipo);
|
||||
tvDescripcion.setText(descripcion != null && !descripcion.isEmpty() ? descripcion : getString(R.string.msg_no_description));
|
||||
|
||||
if (tieneCocina) {
|
||||
layoutExtras.setVisibility(View.VISIBLE);
|
||||
tvCocina.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (telefono == null || telefono.isEmpty() || telefono.equals("Sin teléfono")) {
|
||||
btnLlamar.setVisibility(View.GONE);
|
||||
} else {
|
||||
btnLlamar.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||
intent.setData(Uri.parse("tel:" + telefono));
|
||||
startActivity(intent);
|
||||
});
|
||||
}
|
||||
|
||||
btnComoLlegar.setOnClickListener(v -> {
|
||||
String uri = String.format(java.util.Locale.US, "google.navigation:q=%f,%f&mode=w", latitud, longitud);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
|
||||
intent.setPackage("com.google.android.apps.maps");
|
||||
if (intent.resolveActivity(getPackageManager()) != null) {
|
||||
startActivity(intent);
|
||||
} else {
|
||||
// Fallback a navegador si no hay Google Maps
|
||||
String webUri = String.format(java.util.Locale.US, "https://www.google.com/maps/dir/?api=1&destination=%f,%f&travelmode=walking", latitud, longitud);
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(webUri)));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package es.tatvil.elfarodelperegrino;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Etapa implements Serializable {
|
||||
private String nombre;
|
||||
|
|
@ -14,6 +16,9 @@ public class Etapa implements Serializable {
|
|||
private String hitoHistorico;
|
||||
private double latitud, longitud;
|
||||
private String imagenUrl;
|
||||
private int desnivelPositivo;
|
||||
private int desnivelNegativo;
|
||||
private List<Integer> perfilElevacion;
|
||||
|
||||
public Etapa(String nombre, String origen, String destino, String ruta, String camino, double distancia,
|
||||
int dificultad, String reflexionEspiritual, String hitoHistorico,
|
||||
|
|
@ -30,11 +35,29 @@ public class Etapa implements Serializable {
|
|||
this.latitud = latitud;
|
||||
this.longitud = longitud;
|
||||
this.imagenUrl = "https://picsum.photos/seed/" + nombre.replace(" ", "") + "/800/400";
|
||||
// Valores por defecto para el ejemplo
|
||||
this.desnivelPositivo = (int) (distancia * 15);
|
||||
this.desnivelNegativo = (int) (distancia * 12);
|
||||
this.perfilElevacion = generarPerfilMock(distancia);
|
||||
}
|
||||
|
||||
private List<Integer> generarPerfilMock(double dist) {
|
||||
List<Integer> perfil = new ArrayList<>();
|
||||
int base = 100 + (int)(Math.random() * 200);
|
||||
for (int i = 0; i <= 10; i++) {
|
||||
perfil.add(base + (int)(Math.random() * 150));
|
||||
}
|
||||
return perfil;
|
||||
}
|
||||
|
||||
// Getters
|
||||
public String getImagenUrl() { return imagenUrl; }
|
||||
public List<Integer> getPerfilElevacion() { return perfilElevacion; }
|
||||
public int getDesnivelPositivo() { return desnivelPositivo; }
|
||||
public int getDesnivelNegativo() { return desnivelNegativo; }
|
||||
public void setDesnivelPositivo(int desnivelPositivo) { this.desnivelPositivo = desnivelPositivo; }
|
||||
public void setDesnivelNegativo(int desnivelNegativo) { this.desnivelNegativo = desnivelNegativo; }
|
||||
public void setImagenUrl(String imagenUrl) { this.imagenUrl = imagenUrl; }
|
||||
public String getImagenUrl() { return imagenUrl; }
|
||||
public String getNombre() { return nombre; }
|
||||
public String getOrigen() { return origen; }
|
||||
public String getDestino() { return destino; }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
package es.tatvil.elfarodelperegrino;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Spinner;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.gms.location.FusedLocationProviderClient;
|
||||
import com.google.android.gms.location.LocationServices;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EtapasActivity extends AppCompatActivity {
|
||||
|
||||
private FusedLocationProviderClient fusedLocationClient;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// 1. SIEMPRE debes llamar al super y establecer la vista
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_etapas); // Esto vincula el XML activity_etapas
|
||||
|
||||
// 2. Ahora sí, inicializamos el RecyclerView después de que la vista exista
|
||||
RecyclerView recyclerView = findViewById(R.id.recyclerViewEtapas);
|
||||
|
||||
// 3. Configuración del LayoutManager
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
|
||||
// 4. Configuración del Spinner para seleccionar el camino
|
||||
Spinner spinnerCaminos = findViewById(R.id.spinnerCaminos);
|
||||
String[] opcionesCaminos = {"Norte", "Francés"};
|
||||
|
||||
ArrayAdapter<String> adapterCaminos = new ArrayAdapter<>(this,
|
||||
android.R.layout.simple_spinner_item, opcionesCaminos);
|
||||
adapterCaminos.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinnerCaminos.setAdapter(adapterCaminos);
|
||||
|
||||
// 5. Configuración del Spinner para distancia máxima
|
||||
Spinner spinnerDistancia = findViewById(R.id.spinnerDistancia);
|
||||
String[] opcionesDistancia = {"Sin límite", "15 km", "20 km", "25 km"};
|
||||
ArrayAdapter<String> adapterDistancia = new ArrayAdapter<>(this,
|
||||
android.R.layout.simple_spinner_item, opcionesDistancia);
|
||||
adapterDistancia.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinnerDistancia.setAdapter(adapterDistancia);
|
||||
|
||||
AdapterView.OnItemSelectedListener listener = new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
String camino = spinnerCaminos.getSelectedItem().toString();
|
||||
String distStr = spinnerDistancia.getSelectedItem().toString();
|
||||
double maxDist = Double.MAX_VALUE;
|
||||
if (!distStr.equals("Sin límite")) {
|
||||
maxDist = Double.parseDouble(distStr.split(" ")[0]);
|
||||
}
|
||||
actualizarListaEtapas(camino, maxDist, recyclerView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {}
|
||||
};
|
||||
|
||||
spinnerCaminos.setOnItemSelectedListener(listener);
|
||||
spinnerDistancia.setOnItemSelectedListener(listener);
|
||||
|
||||
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
|
||||
obtenerUbicacionActual();
|
||||
}
|
||||
|
||||
private void actualizarListaEtapas(String camino, double maxDistancia, RecyclerView recyclerView) {
|
||||
List<Etapa> todas = CaminoData.getEtapasPorCamino(this, camino);
|
||||
List<Etapa> filtradas = new ArrayList<>();
|
||||
for (Etapa e : todas) {
|
||||
if (e.getDistancia() <= maxDistancia) {
|
||||
filtradas.add(e);
|
||||
}
|
||||
}
|
||||
EtapaAdapter adapter = new EtapaAdapter(filtradas);
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
private void obtenerUbicacionActual() {
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
|
||||
fusedLocationClient.getLastLocation().addOnSuccessListener(this, location -> {
|
||||
if (location != null) {
|
||||
// Futura implementación: resaltar etapa más cercana
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == 1) {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
obtenerUbicacionActual();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,174 +1,46 @@
|
|||
|
||||
package es.tatvil.elfarodelperegrino;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Spinner;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.android.gms.location.FusedLocationProviderClient;
|
||||
import com.google.android.gms.location.LocationServices;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private FusedLocationProviderClient fusedLocationClient;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// 1. SIEMPRE debes llamar al super y establecer la vista
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main); // Esto vincula el XML activity_main
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// 2. Ahora sí, inicializamos el RecyclerView después de que la vista exista
|
||||
RecyclerView recyclerView = findViewById(R.id.recyclerViewEtapas);
|
||||
|
||||
// 3. Configuración del LayoutManager
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
|
||||
// 4. Configuración del Spinner para seleccionar el camino
|
||||
Spinner spinner = findViewById(R.id.spinnerCaminos);
|
||||
String[] opcionesCaminos = {"Norte", "Francés"};
|
||||
|
||||
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(this,
|
||||
android.R.layout.simple_spinner_item, opcionesCaminos);
|
||||
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(spinnerAdapter);
|
||||
|
||||
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
String caminoSeleccionado = opcionesCaminos[position];
|
||||
actualizarListaEtapas(caminoSeleccionado, recyclerView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
}
|
||||
// --- SECCIÓN RUTA ---
|
||||
findViewById(R.id.btnMap).setOnClickListener(v -> {
|
||||
Intent intent = new Intent(MainActivity.this, EtapasActivity.class);
|
||||
startActivity(intent);
|
||||
});
|
||||
|
||||
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
|
||||
obtenerUbicacionActual();
|
||||
// --- SECCIÓN SERVICIOS ---
|
||||
findViewById(R.id.btnSleep).setOnClickListener(v -> {
|
||||
Toast.makeText(this, "Funcionalidad de Alojamiento próximamente", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
findViewById(R.id.btnFood).setOnClickListener(v -> {
|
||||
Toast.makeText(this, "Funcionalidad de Restaurantes próximamente", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
// --- SECCIÓN MI CAMINO ---
|
||||
findViewById(R.id.btnDiary).setOnClickListener(v -> {
|
||||
Toast.makeText(this, "Funcionalidad de Diario próximamente", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
findViewById(R.id.btnRegister).setOnClickListener(v -> {
|
||||
Toast.makeText(this, "Funcionalidad de Sellar Credencial próximamente", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
findViewById(R.id.btnTraining).setOnClickListener(v -> {
|
||||
Toast.makeText(this, "Funcionalidad de Entrenamiento próximamente", Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
|
||||
private void actualizarListaEtapas(String camino, RecyclerView recyclerView) {
|
||||
List<Etapa> etapas = CaminoData.getEtapasPorCamino(this, camino);
|
||||
EtapaAdapter adapter = new EtapaAdapter(etapas);
|
||||
recyclerView.setAdapter(adapter);
|
||||
}
|
||||
|
||||
private void obtenerUbicacionActual() {
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
|
||||
fusedLocationClient.getLastLocation().addOnSuccessListener(this, location -> {
|
||||
if (location != null) {
|
||||
double miLat = location.getLatitude();
|
||||
double miLon = location.getLongitude();
|
||||
// Aquí se compararía con las etapas
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == 1) {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
obtenerUbicacionActual();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Etapa> cargarEtapasDesdeJSON() {
|
||||
List<Etapa> lista = new ArrayList<>();
|
||||
try {
|
||||
InputStream is = getResources().openRawResource(R.raw.etapas);
|
||||
byte[] buffer = new byte[is.available()];
|
||||
is.read(buffer);
|
||||
is.close();
|
||||
String json = new String(buffer, "UTF-8");
|
||||
|
||||
JSONArray jsonArray = new JSONArray(json);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject obj = jsonArray.getJSONObject(i);
|
||||
lista.add(new Etapa(
|
||||
obj.getString("nombre"),
|
||||
obj.optString("origen", ""),
|
||||
obj.optString("destino", ""),
|
||||
obj.optString("ruta", obj.optString("origen") + " - " + obj.optString("destino")),
|
||||
obj.optString("camino", "Norte"),
|
||||
obj.getDouble("distancia"),
|
||||
obj.optInt("dificultad", 0),
|
||||
obj.optString("reflexionEspiritual", obj.optString("reflexion", "")),
|
||||
obj.optString("hitoHistorico", obj.optString("historia", "")),
|
||||
obj.getDouble("latitud"),
|
||||
obj.getDouble("longitud")
|
||||
));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return lista;
|
||||
}
|
||||
|
||||
private List<Etapa> leerEtapasDesdeRaw() {
|
||||
List<Etapa> lista = new ArrayList<>();
|
||||
try {
|
||||
// Abrimos el archivo etapas.json que debes crear en res/raw
|
||||
InputStream is = getResources().openRawResource(R.raw.etapas);
|
||||
int size = is.available();
|
||||
byte[] buffer = new byte[size];
|
||||
is.read(buffer);
|
||||
is.close();
|
||||
|
||||
String jsonString = new String(buffer, "UTF-8");
|
||||
JSONArray jsonArray = new JSONArray(jsonString);
|
||||
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject obj = jsonArray.getJSONObject(i);
|
||||
lista.add(new Etapa(
|
||||
obj.getString("nombre"),
|
||||
obj.optString("origen", ""),
|
||||
obj.optString("destino", ""),
|
||||
obj.optString("ruta", obj.optString("origen") + " - " + obj.optString("destino")),
|
||||
obj.optString("camino", "Norte"),
|
||||
obj.getDouble("distancia"),
|
||||
obj.optInt("dificultad", 0),
|
||||
obj.optString("reflexionEspiritual", obj.optString("reflexion", "")),
|
||||
obj.optString("hitoHistorico", obj.optString("historia", "")),
|
||||
obj.getDouble("latitud"),
|
||||
obj.getDouble("longitud")
|
||||
));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return lista;
|
||||
}
|
||||
|
||||
// Método para calcular distancia entre dos puntos (Fórmula de Haversine simplificada)
|
||||
public double calcularDistancia(double lat1, double lon1, double lat2, double lon2) {
|
||||
double theta = lon1 - lon2;
|
||||
double dist = Math.sin(Math.toRadians(lat1)) * Math.sin(Math.toRadians(lat2)) +
|
||||
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
|
||||
Math.cos(Math.toRadians(theta));
|
||||
dist = Math.acos(dist);
|
||||
dist = Math.toDegrees(dist);
|
||||
return dist * 60 * 1.1515 * 1.609344; // Retorna Kilómetros
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// Aquí conectas los botones
|
||||
findViewById(R.id.btnTraining).setOnClickListener(v -> {
|
||||
// TODO: abrir pantalla de entrenamiento
|
||||
});
|
||||
|
||||
findViewById(R.id.btnDiary).setOnClickListener(v -> {
|
||||
// TODO: abrir pantalla del diario
|
||||
});
|
||||
|
||||
// ... y así con los demás
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package es.tatvil.elfarodelperegrino;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class SimpleServicioAdapter extends RecyclerView.Adapter<SimpleServicioAdapter.ViewHolder> {
|
||||
|
||||
private List<?> items;
|
||||
private double refLat, refLon;
|
||||
|
||||
public SimpleServicioAdapter(List<?> items, double refLat, double refLon) {
|
||||
this.items = items;
|
||||
this.refLat = refLat;
|
||||
this.refLon = refLon;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.item_albergue, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
Object item = items.get(position);
|
||||
String nombre = "";
|
||||
double lat = 0, lon = 0;
|
||||
String tipo = "";
|
||||
|
||||
if (item instanceof Iglesia) {
|
||||
Iglesia i = (Iglesia) item;
|
||||
nombre = i.getNombre();
|
||||
lat = i.getLatitud();
|
||||
lon = i.getLongitud();
|
||||
tipo = "Iglesia";
|
||||
} else if (item instanceof Restaurante) {
|
||||
Restaurante r = (Restaurante) item;
|
||||
nombre = r.getNombre();
|
||||
lat = r.getLatitud();
|
||||
lon = r.getLongitud();
|
||||
tipo = "Restaurante";
|
||||
}
|
||||
|
||||
holder.tvNombre.setText(nombre);
|
||||
holder.tvTipo.setText(tipo);
|
||||
holder.tvTelefono.setVisibility(View.GONE);
|
||||
|
||||
float[] results = new float[1];
|
||||
android.location.Location.distanceBetween(refLat, refLon, lat, lon, results);
|
||||
float distanciaKm = results[0] / 1000;
|
||||
holder.tvDistancia.setText(String.format(Locale.getDefault(), "A %.1f km", distanciaKm));
|
||||
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(v.getContext(), DetalleServicioActivity.class);
|
||||
intent.putExtra("objeto", (Serializable) item);
|
||||
v.getContext().startActivity(intent);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView tvNombre, tvTipo, tvDistancia, tvTelefono;
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
tvNombre = itemView.findViewById(R.id.tvAlbergueNombre);
|
||||
tvTipo = itemView.findViewById(R.id.tvAlbergueTipo);
|
||||
tvDistancia = itemView.findViewById(R.id.tvAlbergueDistancia);
|
||||
tvTelefono = itemView.findViewById(R.id.tvAlbergueTelefono);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,170 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:fillColor="#003366"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<!-- Subtle circular glow in the center -->
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
||||
android:pathData="M54,54m-40,0a40,40 0,1 1,80 0a40,40 0,1 1,-80 0">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:centerX="54"
|
||||
android:centerY="54"
|
||||
android:gradientRadius="45"
|
||||
android:type="radial">
|
||||
<item android:color="#1AFFFFFF" android:offset="0.0" />
|
||||
<item android:color="#00FFFFFF" android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
</vector>
|
||||
|
|
@ -4,27 +4,62 @@
|
|||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
|
||||
<!-- Lighthouse Body -->
|
||||
<path
|
||||
android:pathData="M44,85 L64,85 L60,35 L48,35 Z"
|
||||
android:fillColor="#E0E0E0" />
|
||||
<path
|
||||
android:pathData="M46,55 L62,55 L61,65 L47,65 Z"
|
||||
android:fillColor="#B71C1C" /> <!-- Red stripe -->
|
||||
|
||||
<!-- Top Lantern Room -->
|
||||
<path
|
||||
android:pathData="M46,35 L62,35 L62,25 L46,25 Z"
|
||||
android:fillColor="#333333" />
|
||||
<path
|
||||
android:pathData="M48,25 L60,25 L54,18 Z"
|
||||
android:fillColor="#333333" />
|
||||
|
||||
<!-- Light Beam (Left) -->
|
||||
<path
|
||||
android:pathData="M48,30 L15,15 L15,45 Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:startX="48"
|
||||
android:startY="30"
|
||||
android:endX="15"
|
||||
android:endY="30"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
<item android:color="#B3FFD700" android:offset="0.0" />
|
||||
<item android:color="#00FFD700" android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
|
||||
<!-- Light Beam (Right) -->
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
android:pathData="M60,30 L93,15 L93,45 Z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startX="60"
|
||||
android:startY="30"
|
||||
android:endX="93"
|
||||
android:endY="30"
|
||||
android:type="linear">
|
||||
<item android:color="#B3FFD700" android:offset="0.0" />
|
||||
<item android:color="#00FFD700" android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
|
||||
<!-- Scallop Shell (Concha de Santiago) at the bottom -->
|
||||
<path
|
||||
android:pathData="M54,88 C48,88 44,92 44,96 C44,101 48,104 54,104 C60,104 64,101 64,96 C64,92 60,88 54,88 Z"
|
||||
android:fillColor="#FFD700" />
|
||||
<!-- Ridges on the shell -->
|
||||
<path android:pathData="M54,90 L54,102" android:strokeColor="#B29600" android:strokeWidth="1" />
|
||||
<path android:pathData="M50,91 L52,101" android:strokeColor="#B29600" android:strokeWidth="1" />
|
||||
<path android:pathData="M58,91 L56,101" android:strokeColor="#B29600" android:strokeWidth="1" />
|
||||
|
||||
</vector>
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- Saludo -->
|
||||
<TextView
|
||||
android:id="@+id/txtGreeting"
|
||||
android:text="Buen Camino, Tatiana"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- Fecha -->
|
||||
<TextView
|
||||
android:id="@+id/txtDate"
|
||||
android:text="Sábado, 2 de mayo de 2026"
|
||||
android:textSize="16sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<!-- Tarjeta del tiempo -->
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:background="#1E88E5"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtLocation"
|
||||
android:text="📍 Las Rozas de Madrid"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtWeatherToday"
|
||||
android:text="Hoy: 11ºC - 19ºC · 60%"
|
||||
android:textColor="@android:color/white"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtWeatherTomorrow"
|
||||
android:text="Mañana: 14ºC - 20ºC · 17%"
|
||||
android:textColor="@android:color/white"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Grid de botones -->
|
||||
<GridLayout
|
||||
android:id="@+id/gridButtons"
|
||||
android:columnCount="2"
|
||||
android:rowCount="4"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!-- Cada botón -->
|
||||
<Button
|
||||
android:id="@+id/btnTraining"
|
||||
android:text="Entrenamiento"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnMap"
|
||||
android:text="Mapa y etapas"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnFood"
|
||||
android:text="Dónde comer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnSleep"
|
||||
android:text="Dónde dormir"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnServices"
|
||||
android:text="Servicios útiles"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnRegister"
|
||||
android:text="Registrar paso"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnDiary"
|
||||
android:text="Mi diario"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="8dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnMessages"
|
||||
android:text="Mensajes del camino"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="80dp"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="8dp"/>
|
||||
</GridLayout>
|
||||
|
||||
<!-- Frase final -->
|
||||
<TextView
|
||||
android:id="@+id/txtQuote"
|
||||
android:text="El camino me enseñó que el verdadero lujo es el que nos dedicamos a nosotros mismos."
|
||||
android:layout_marginTop="24dp"
|
||||
android:textSize="14sp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
|
@ -28,62 +28,155 @@
|
|||
android:text="Nombre de la Etapa"
|
||||
android:layout_marginBottom="16dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleDistancia"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="18sp"
|
||||
android:textColor="#BBBBBB"
|
||||
android:text="Distancia: 24 km"
|
||||
android:layout_marginBottom="24dp"/>
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Historia y Hitos"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/text_primary"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Distancia"
|
||||
android:textColor="#BBBBBB"
|
||||
android:textSize="12sp"/>
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleDistancia"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/text_primary"
|
||||
android:text="24 km"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleHistoria"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/text_primary"
|
||||
android:text="Cargando historia..."
|
||||
android:layout_marginBottom="24dp"/>
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Desnivel +"
|
||||
android:textColor="#BBBBBB"
|
||||
android:textSize="12sp"/>
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleDesnivelPos"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#4CAF50"
|
||||
android:text="+450m"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Reflexión Espiritual"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/text_primary"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Desnivel -"
|
||||
android:textColor="#BBBBBB"
|
||||
android:textSize="12sp"/>
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleDesnivelNeg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#F44336"
|
||||
android:text="-380m"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleReflexion"
|
||||
<androidx.cardview.widget.CardView
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/text_primary"
|
||||
android:text="Cargando reflexión..."
|
||||
android:layout_marginBottom="16dp"/>
|
||||
app:cardBackgroundColor="#222222"
|
||||
app:cardCornerRadius="8dp"
|
||||
android:layout_marginBottom="16dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="12dp">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Perfil de Elevación"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
<com.github.mikephil.charting.charts.LineChart
|
||||
android:id="@+id/elevationChart"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="150dp"/>
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleClima"
|
||||
<androidx.cardview.widget.CardView
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:textColor="#FFEB3B"
|
||||
android:text="Clima: --"
|
||||
android:layout_marginBottom="24dp"/>
|
||||
app:cardBackgroundColor="#222222"
|
||||
app:cardCornerRadius="8dp"
|
||||
android:layout_marginBottom="24dp">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="12dp">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Previsión del Tiempo (Próximos días)"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleClima"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textColor="#FFEB3B"
|
||||
android:text="Cargando clima actual..."/>
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#444444"
|
||||
android:layout_marginVertical="8dp"/>
|
||||
<LinearLayout
|
||||
android:id="@+id/layoutForecast"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="3"/>
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnVerClima"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/btnVerMapa"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Ver Clima Actual"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
android:text="Ver en Mapa / GPS"
|
||||
android:backgroundTint="#1976D2"
|
||||
android:layout_marginBottom="24dp"
|
||||
app:icon="@android:drawable/ic_dialog_map"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnVerAlbergues"
|
||||
|
|
@ -105,7 +198,45 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Restaurantes"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"/>
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
android:layout_marginBottom="24dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Historia del lugar"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="18sp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleHistoria"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#CCCCCC"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="Cargando historia..."/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Reflexión Espiritual"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textStyle="bold"
|
||||
android:textSize="18sp"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleReflexion"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#CCCCCC"
|
||||
android:textSize="14sp"
|
||||
android:fontStyle="italic"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="Cargando reflexión..."/>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,117 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/spiritual_black">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardBackgroundColor="@color/spiritual_surface"
|
||||
app:cardCornerRadius="24dp"
|
||||
app:strokeWidth="1dp"
|
||||
app:strokeColor="@color/spiritual_gold">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleNombre"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleTipo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/label_category"
|
||||
android:textColor="@color/spiritual_gold"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginVertical="16dp"
|
||||
android:background="@color/spiritual_text_dim"
|
||||
android:alpha="0.3" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleDescripcion"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/msg_no_description"
|
||||
android:textColor="@color/spiritual_text_bright"
|
||||
android:textSize="16sp"
|
||||
android:lineSpacingExtra="4dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layoutExtras"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDetalleCocina"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/msg_has_kitchen"
|
||||
android:textColor="@color/accent_green"
|
||||
android:textSize="14sp" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnLlamar"
|
||||
style="@style/Widget.MaterialComponents.Button.Icon"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:text="@string/action_call"
|
||||
app:icon="@android:drawable/ic_menu_call"
|
||||
app:cornerRadius="16dp"
|
||||
android:backgroundTint="@color/maritime_blue_deep"
|
||||
android:textColor="@color/white"
|
||||
android:layout_marginBottom="12dp" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btnComoLlegar"
|
||||
style="@style/Widget.MaterialComponents.Button.Icon"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:text="@string/action_directions"
|
||||
app:icon="@android:drawable/ic_menu_directions"
|
||||
app:cornerRadius="16dp"
|
||||
android:backgroundTint="@color/spiritual_surface"
|
||||
app:strokeColor="@color/spiritual_gold"
|
||||
app:strokeWidth="1dp"
|
||||
android:textColor="@color/white" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".EtapasActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/headerLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Selecciona el Camino:"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginStart="8dp"/>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerCaminos"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:background="@android:drawable/btn_dropdown" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Distancia máxima por etapa:"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginStart="8dp"/>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerDistancia"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:background="@android:drawable/btn_dropdown" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerViewEtapas"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:background="@color/dark_background"
|
||||
app:layout_constraintTop_toBottomOf="@id/headerLayout"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -1,28 +1,314 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
android:background="@color/spiritual_black"
|
||||
android:fillViewport="true">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinnerCaminos"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:background="@android:drawable/btn_dropdown"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerViewEtapas"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:background="@color/dark_background"
|
||||
app:layout_constraintTop_toBottomOf="@id/spinnerCaminos"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="40dp">
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<!-- Fondo de Cabecera -->
|
||||
<View
|
||||
android:id="@+id/headerBackground"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="220dp"
|
||||
android:background="@color/maritime_blue_deep"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtGreeting"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginTop="56dp"
|
||||
android:text="@string/welcome_message"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="32sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<!-- Tarjeta de Estado Flotante -->
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/statusCard"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginTop="-50dp"
|
||||
app:cardBackgroundColor="@color/spiritual_surface"
|
||||
app:cardCornerRadius="24dp"
|
||||
app:cardElevation="10dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/headerBackground"
|
||||
app:strokeWidth="0dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="20dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtLocation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/location_sample"
|
||||
android:textColor="@color/spiritual_gold"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/txtWeatherToday"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/weather_sample"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:background="@color/spiritual_text_dim" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="@string/date_sample"
|
||||
android:textColor="@color/spiritual_gold"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<!-- SECCIÓN: RUTA (DESTACADA) -->
|
||||
<TextView
|
||||
android:id="@+id/labelRuta"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:text="@string/label_your_route"
|
||||
android:letterSpacing="0.1"
|
||||
android:textColor="@color/spiritual_text_dim"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/statusCard" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/btnMap"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="150dp"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:cardBackgroundColor="@color/spiritual_surface"
|
||||
app:cardCornerRadius="24dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/labelRuta"
|
||||
app:strokeColor="@color/maritime_blue_mary"
|
||||
app:strokeWidth="1dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="24dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:text="@string/action_map"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="22sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:alpha="0.1"
|
||||
android:src="@android:drawable/ic_menu_mapmode"
|
||||
app:tint="@color/white" />
|
||||
</RelativeLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<!-- SECCIÓN: SERVICIOS -->
|
||||
<TextView
|
||||
android:id="@+id/labelServicios"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:text="@string/label_services"
|
||||
android:letterSpacing="0.1"
|
||||
android:textColor="@color/spiritual_text_dim"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/btnMap" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layoutServicios"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="18dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintTop_toBottomOf="@id/labelServicios">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/btnSleep"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="110dp"
|
||||
android:layout_margin="6dp"
|
||||
android:layout_weight="1"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:cardBackgroundColor="@color/spiritual_surface"
|
||||
app:cardCornerRadius="20dp">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/action_sleep"
|
||||
android:textColor="@color/spiritual_text_bright"
|
||||
android:textStyle="bold" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/btnFood"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="110dp"
|
||||
android:layout_margin="6dp"
|
||||
android:layout_weight="1"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:cardBackgroundColor="@color/spiritual_surface"
|
||||
app:cardCornerRadius="20dp">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/action_food"
|
||||
android:textColor="@color/spiritual_text_bright"
|
||||
android:textStyle="bold" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- SECCIÓN: MI CAMINO -->
|
||||
<TextView
|
||||
android:id="@+id/labelPersonal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="@string/label_personal"
|
||||
android:letterSpacing="0.1"
|
||||
android:textColor="@color/spiritual_text_dim"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/layoutServicios" />
|
||||
|
||||
<GridLayout
|
||||
android:id="@+id/gridPersonal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="18dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:columnCount="3"
|
||||
app:layout_constraintTop_toBottomOf="@id/labelPersonal">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/btnDiary"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="90dp"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="6dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:cardBackgroundColor="@color/spiritual_surface"
|
||||
app:cardCornerRadius="20dp">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/action_diary"
|
||||
android:textColor="@color/spiritual_text_bright"
|
||||
android:textSize="12sp" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/btnRegister"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="90dp"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="6dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:cardBackgroundColor="@color/spiritual_surface"
|
||||
app:cardCornerRadius="20dp">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/action_seal_short"
|
||||
android:textColor="@color/spiritual_text_bright"
|
||||
android:textSize="12sp" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/btnTraining"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="90dp"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="6dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:cardBackgroundColor="@color/spiritual_surface"
|
||||
app:cardCornerRadius="20dp">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/action_train_short"
|
||||
android:textColor="@color/spiritual_text_bright"
|
||||
android:textSize="12sp" />
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</GridLayout>
|
||||
|
||||
<!-- FRASE FINAL -->
|
||||
<TextView
|
||||
android:id="@+id/txtQuote"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="48dp"
|
||||
android:layout_marginHorizontal="48dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/quote_spiritual"
|
||||
android:textColor="@color/spiritual_gold"
|
||||
android:textSize="15sp"
|
||||
android:alpha="0.8"
|
||||
android:lineSpacingExtra="6dp"
|
||||
android:textStyle="italic"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/gridPersonal" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
||||
|
|
@ -3,5 +3,11 @@
|
|||
"nombre": "Pulperia A Garnacha",
|
||||
"latitud": 42.91390034545274,
|
||||
"longitud": -8.011660067243549
|
||||
},
|
||||
{
|
||||
"nombre": "Bar Manuel",
|
||||
"latitud": 42.931718288986296,
|
||||
"longitud":-8.127124619996351
|
||||
}
|
||||
|
||||
]
|
||||
|
|
@ -1,3 +1,26 @@
|
|||
<resources>
|
||||
<string name="app_name">El Faro del Peregrino</string>
|
||||
<string name="welcome_message">Buen Camino,\nTatiana</string>
|
||||
<string name="label_your_route">TU RUTA</string>
|
||||
<string name="label_services">SERVICIOS</string>
|
||||
<string name="label_personal">MI CAMINO</string>
|
||||
<string name="action_map">Mapa interactivo y\nEtapas del Camino</string>
|
||||
<string name="action_sleep">Dónde\nDormir</string>
|
||||
<string name="action_food">Dónde\nComer</string>
|
||||
<string name="action_diary">Mi\nDiario</string>
|
||||
<string name="action_register">Sellar\nCredencial</string>
|
||||
<string name="action_training">Preparación</string>
|
||||
<string name="action_train_short">Entrenar</string>
|
||||
<string name="action_seal_short">Sellar</string>
|
||||
<string name="weather_sample">19ºC · Cielo despejado</string>
|
||||
<string name="date_sample">2 Mayo\nSábado</string>
|
||||
<string name="location_sample">📍 Las Rozas de Madrid</string>
|
||||
<string name="quote_spiritual">\"El camino me enseñó que el verdadero lujo es el que nos dedicamos a nosotros mismos.\"</string>
|
||||
<string name="label_category">Categoría</string>
|
||||
<string name="action_call">Llamar</string>
|
||||
<string name="action_directions">Cómo llegar</string>
|
||||
<string name="msg_no_description">Sin descripción disponible.</string>
|
||||
<string name="msg_has_kitchen">🍳 Dispone de cocina</string>
|
||||
<string name="msg_interest_place">Lugar de interés espiritual y arquitectónico en el Camino.</string>
|
||||
<string name="msg_food_place">Disfruta de la gastronomía local en este establecimiento.</string>
|
||||
</resources>
|
||||
|
|
@ -9,6 +9,7 @@ activity = "1.13.0"
|
|||
constraintlayout = "2.2.1"
|
||||
volley = "1.2.1"
|
||||
glide = "4.16.0"
|
||||
mpandroidchart = "v3.1.0"
|
||||
|
||||
[libraries]
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
|
|
@ -21,6 +22,7 @@ constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayo
|
|||
volley = { group = "com.android.volley", name = "volley", version.ref = "volley" }
|
||||
glide = { group = "com.github.bumptech.glide", name = "glide", version.ref = "glide" }
|
||||
glide-compiler = { group = "com.github.bumptech.glide", name = "compiler", version.ref = "glide" }
|
||||
mpandroidchart = { group = "com.github.PhilJay", name = "MPAndroidChart", version.ref = "mpandroidchart" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ dependencyResolutionManagement {
|
|||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url = uri("https://jitpack.io") }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue