Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions android_weather_app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.gradle/
build/
app/build/
local.properties
36 changes: 36 additions & 0 deletions android_weather_app/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
plugins {
id 'com.android.application'
}

android {
namespace 'com.example.weatherapp'
compileSdk 34

defaultConfig {
applicationId "com.example.weatherapp"
minSdk 24
targetSdk 34
versionCode 1
versionName "1.0"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.recyclerview:recyclerview:1.3.1'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}
15 changes: 15 additions & 0 deletions android_weather_app/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:label="Weather App"
android:theme="@style/Theme.WeatherApp">
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.weatherapp;

import java.util.List;
import com.google.gson.annotations.SerializedName;

public class Hourly {
private List<String> time;
@SerializedName("temperature_2m")
private List<Double> temperature2m;

public List<String> getTime() { return time; }
public List<Double> getTemperature2m() { return temperature2m; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.example.weatherapp;

import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class MainActivity extends AppCompatActivity {

private RecyclerView recyclerView;
private WeatherAdapter adapter;

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

recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

fetchWeather();
}

private void fetchWeather() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.open-meteo.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();

WeatherService service = retrofit.create(WeatherService.class);

Call<List<WeatherResponse>> call = service.getForecast(
"37.3861,37.4419",
"-122.0839,-122.1430",
"temperature_2m",
"America/Los_Angeles"
);

call.enqueue(new Callback<List<WeatherResponse>>() {
@Override
public void onResponse(Call<List<WeatherResponse>> call, Response<List<WeatherResponse>> response) {
if (response.isSuccessful() && response.body() != null && response.body().size() >= 2) {
WeatherResponse mvData = response.body().get(0);
WeatherResponse paData = response.body().get(1);

List<String> times = mvData.getHourly().getTime();
List<Double> tempsMV = mvData.getHourly().getTemperature2m();
List<Double> tempsPA = paData.getHourly().getTemperature2m();

adapter = new WeatherAdapter(times, tempsMV, tempsPA);
recyclerView.setAdapter(adapter);
} else {
Log.e("WeatherApp", "Response unsuccessful or empty");
}
}

@Override
public void onFailure(Call<List<WeatherResponse>> call, Throwable t) {
Log.e("WeatherApp", "API Call failed", t);
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.example.weatherapp;

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.util.List;

public class WeatherAdapter extends RecyclerView.Adapter<WeatherAdapter.ViewHolder> {

private List<String> times;
private List<Double> tempsMV;
private List<Double> tempsPA;

public WeatherAdapter(List<String> times, List<Double> tempsMV, List<Double> tempsPA) {
this.times = times;
this.tempsMV = tempsMV;
this.tempsPA = tempsPA;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_weather, parent, false);
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
String time = times.get(position);
if (time.contains("T")) {
time = time.split("T")[1];
}

holder.tvTime.setText(time);

if (position < tempsMV.size()) {
holder.tvMvTemp.setText(String.format("%.1f°C", tempsMV.get(position)));
} else {
holder.tvMvTemp.setText("");
}

if (position < tempsPA.size()) {
holder.tvPaTemp.setText(String.format("%.1f°C", tempsPA.get(position)));
} else {
holder.tvPaTemp.setText("");
}
}

@Override
public int getItemCount() {
return times != null ? times.size() : 0;
}

static class ViewHolder extends RecyclerView.ViewHolder {
TextView tvTime;
TextView tvMvTemp;
TextView tvPaTemp;

ViewHolder(View itemView) {
super(itemView);
tvTime = itemView.findViewById(R.id.tv_time);
tvMvTemp = itemView.findViewById(R.id.tv_mv_temp);
tvPaTemp = itemView.findViewById(R.id.tv_pa_temp);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.weatherapp;

public class WeatherResponse {
private double latitude;
private double longitude;
private Hourly hourly;

public double getLatitude() { return latitude; }
public double getLongitude() { return longitude; }
public Hourly getHourly() { return hourly; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.weatherapp;

import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;

public interface WeatherService {
@GET("v1/forecast")
Call<List<WeatherResponse>> getForecast(
@Query("latitude") String latitude,
@Query("longitude") String longitude,
@Query("hourly") String hourly,
@Query("timezone") String timezone
);
}
65 changes: 65 additions & 0 deletions android_weather_app/app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black">

<TextView
android:id="@+id/tv_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Weather Forecast"
android:textColor="@color/white"
android:textSize="24sp"
android:textStyle="bold"
android:padding="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

<LinearLayout
android:id="@+id/header_row"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp"
android:background="@color/dark_gray"
app:layout_constraintTop_toBottomOf="@id/tv_header"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Time"
android:textColor="@color/white"
android:textStyle="bold"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Mtn View"
android:textColor="@color/white"
android:gravity="end"
android:textStyle="bold"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Palo Alto"
android:textColor="@color/white"
android:gravity="end"
android:textStyle="bold"/>
</LinearLayout>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/header_row"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
38 changes: 38 additions & 0 deletions android_weather_app/app/src/main/res/layout/item_weather.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp"
android:background="@color/black">

<TextView
android:id="@+id/tv_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Time"
android:textColor="@color/white"
android:textSize="16sp" />

<TextView
android:id="@+id/tv_mv_temp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="MV"
android:textColor="@color/light_gray"
android:textSize="16sp"
android:gravity="end"/>

<TextView
android:id="@+id/tv_pa_temp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="PA"
android:textColor="@color/light_gray"
android:textSize="16sp"
android:gravity="end"/>

</LinearLayout>
12 changes: 12 additions & 0 deletions android_weather_app/app/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="dark_gray">#FF333333</color>
<color name="light_gray">#FFCCCCCC</color>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
</resources>
10 changes: 10 additions & 0 deletions android_weather_app/app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.WeatherApp" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">@color/black</item>
<item name="colorPrimaryDark">@color/black</item>
<item name="colorAccent">@color/white</item>
<item name="android:statusBarColor">@color/black</item>
<item name="android:windowBackground">@color/black</item>
</style>
</resources>
20 changes: 20 additions & 0 deletions android_weather_app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.1.0'
}
}

allprojects {
repositories {
google()
mavenCentral()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
1 change: 1 addition & 0 deletions android_weather_app/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
android.useAndroidX=true
1 change: 1 addition & 0 deletions android_weather_app/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include ':app'