How to create a Weather App on Android

Hello peeps,

Time for another Blog Post this year. Well, last month I had attended an "Android Internship" Workshop at our college, which is actually a CS With Android course offered by Google. Since many of my colleagues didn't know Java, we were given a tour of Java programming for the first three days, followed by a session on AI2 App inventor by MIT. Later did we started doing the actual beast : Developing Apps with Android Studio.

First of All, I would Like to thank Chandru etta, for helping us learn all the amazing things during these 12 days.

After the workshop ended, we were given the assignment to build an app under an incentive that the best ones would be sent to Google. I finished building one yesterday. It's a weather app called Simple Weather. The app was made by concepts which were not taught to us in the class.

FINDING THE SOURCE CODE

Yeah, folks, my app is completely open source and hosted on GitHub. The source of my app can be found here

HOW DID I MAKE THIS MIRACLE?

Now, folks, you might have entered an address on your mobile browser, and it loads up the webpage. But here's the thing, there are various steps running within the browser just to display the page, you just don't see that happening (apart from the loading spinner or the progress bar). My app is no different. There are various processes underlying just to display the weather data associated with the current City.

Implementation

Here's how I made my app working:

  1. Created a URL object, which has the web address to retrieve the input (The city is retrieved from a SharedPreferences File).
  2. Opened connection to the URL Objects, thereby successfully connecting to the internet.
  3. Created a BufferedReader Object, which reads the output we get from the URL (in JSON format)
  4. The output from the URL is converted to a StringBuffer. BufferedReader reads every line of the output and then appends it to the StringBuffer
  5. Then this output is converted to a JSONObject by converting the StringBuffer to a String.
  6. This JSONObject is then returned to my main Fragment (not Activity)
  7. This JSONObject is rendered by the renderWeather method in my main Fragment.
  8. This method does the job of displaying all the data on the main Screen.
  9. The onCreateView() method of this fragment maps the Resources from the Java file (should be a class instead) to the Resources in the Layout.xml file

CODE


So okay, here's my code:

1. WeatherActivity.java

package com.a5corp.weather;

import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class WeatherActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_weather);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new WeatherFragment())
.commit();
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.weather, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.change_city){
showInputDialog();
}
return false;
}

private void showInputDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Change city");
final EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
builder.setView(input);
builder.setPositiveButton("Go", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
changeCity(input.getText().toString());
}
});
builder.show();
}

public void changeCity(String city){
WeatherFragment wf = (WeatherFragment)getSupportFragmentManager()
.findFragmentById(R.id.container);
wf.changeCity(city);
new CityPreference(this).setCity(city);
}

public static class PlaceholderFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";

public PlaceholderFragment() {
}

public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_weather, container, false);
return rootView;
}
}

/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {

public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}

@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
return PlaceholderFragment.newInstance(position + 1);
}

@Override
public int getCount() {
// Show 3 total pages.
return 3;
}

@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "SECTION 1";
case 1:
return "SECTION 2";
case 2:
return "SECTION 3";
}
return null;
}
}
}

2. WeatherFragment.java

package com.a5corp.weather;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONObject;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Calendar;
import java.util.Locale;

public class WeatherFragment extends Fragment {
Typeface weatherFont;
Button button;
ProgressDialog pd;
TextView detailsField[] = new TextView[10] , weatherIcon[] = new TextView[11];
TextView windView , humidityView , directionView, dailyView, updatedField, cityField;
double tc;
Handler handler;
int Clicks = 0;
private void updateWeatherData(final String city){
new Thread(){
public void run(){
final JSONObject[] json = RemoteFetch.getJSON(getActivity(), city);
if(json == null){
handler.post(new Runnable(){
public void run(){
Toast.makeText(getActivity(),
getActivity().getString(R.string.place_not_found),
Toast.LENGTH_LONG).show();
}
});
} else {
handler.post(new Runnable(){
public void run(){
renderWeather(json);
}
});
}
}
}.start();
}

public void Units(JSONObject json1)
{
try {
int bool = Clicks % 2;
switch (bool) {
case 0 :
double Fah = json1.getJSONObject("main").getDouble("temp") * 1.8 + 32;
int F = (int) Fah;
button.setText(Integer.toString(F) + "°F");
++Clicks;
break;
case 1:
button.setText((int) Math.round(json1.getJSONObject("main").getDouble("temp")) + "°C");
++Clicks;
break;
}
}
catch (Exception ex)
{
Log.e("Not Found" , "BFFK");
}
}

public void changeCity(String city)
{
updateWeatherData(city);
}

private void renderWeather(JSONObject[] jsonj){
try {
button.setVisibility(View.INVISIBLE);
Clicks = 0;
Log.i("Showed" , "Done");
final JSONObject json = jsonj[0] , json1 = jsonj[1];
tc = json1.getJSONObject("main").getDouble("temp");
int a = (int) Math.round(json1.getJSONObject("main").getDouble("temp"));
//button.setText("°C"); //℃
cityField.setText(json.getJSONObject("city").getString("name").toUpperCase(Locale.US) +
", " +
json.getJSONObject("city").getString("country"));
cityField.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
AlertDialog alertDialog = new AlertDialog.Builder(getActivity()).create(); //Read Update
alertDialog.setTitle("City Information");
try {
alertDialog.setMessage(json.getJSONObject("city").getString("name").toUpperCase(Locale.US) +
", " +
json.getJSONObject("city").getString("country"));
alertDialog.show();
Log.i("Load", "BFFK");
} catch (Exception ex) {
Log.e("Error", "FFFF");
}
}
});
Log.i("Location" , "Location Received");
JSONObject details[] = new JSONObject[10];
for (int i = 0; i < 10; ++i)
{
details[i] = json.getJSONArray("list").getJSONObject(i);
}
Log.i("Objects" , "JSON Objects Created");
for (int i = 0; i < 10; ++i)
{
final JSONObject J = details[i];
String date1 = details[i].getString("dt");
Date expiry = new Date(Long.parseLong(date1) * 1000);
String date = new SimpleDateFormat("EE, dd").format(expiry);
SpannableString ss1= new SpannableString(date + "\n"
+ details[i].getJSONObject("temp").getLong("max") + "°" + " "
+ details[i].getJSONObject("temp").getLong("min") + "°" + "\n");
ss1.setSpan(new RelativeSizeSpan(1.1f), 0,7, 0); // set size
ss1.setSpan(new RelativeSizeSpan(1.4f) , 8 , 11 , 0);
detailsField[i].setText(ss1);
Log.i("Details[" + Integer.toString(i) + "]", "Infor String " + Integer.toString(i + 1) + " loaded");
setWeatherIcon(details[i].getJSONArray("weather").getJSONObject(0).getInt("id") , i);
detailsField[i].setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
AlertDialog alertDialog = new AlertDialog.Builder(getActivity()).create(); //Read Update
alertDialog.setTitle("Weather Information");
try{
String date1 = J.getString("dt");
Date expiry = new Date(Long.parseLong(date1) * 1000);
String date = new SimpleDateFormat("EE, dd MMMM yyyy").format(expiry);
alertDialog.setMessage(date +
"\n" + J.getJSONArray("weather").getJSONObject(0).getString("description").toUpperCase(Locale.US) +
"\n" + "Maximum: " + J.getJSONObject("temp").getLong("max") + " ℃" +
"\n" + "Minimum: " + J.getJSONObject("temp").getLong("min") + " ℃" +
"\n" + "Morning: " + J.getJSONObject("temp").getLong("morn") + " ℃" +
"\n" + "At Night: " + J.getJSONObject("temp").getLong("night") + " ℃" +
"\n" + "Evening: " + J.getJSONObject("temp").getLong("eve") + " ℃" +
"\n" + "Humidity: " + J.getString("humidity") + "%" +
"\n" + "Pressure: " + J.getString("pressure") + " hPa" +
"\n" + "Wind: " + J.getString("speed") + "km/h");
alertDialog.show();
Log.i("Load" , "BFFK");}
catch (Exception e) {
Log.e("Error", "FO");
}
}
});
weatherIcon[i].setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
AlertDialog alertDialog = new AlertDialog.Builder(getActivity()).create(); //Read Update
alertDialog.setTitle("Weather Information");
try{
String date1 = J.getString("dt");
Date expiry = new Date(Long.parseLong(date1) * 1000);
String date = new SimpleDateFormat("EE, dd MMMM yyyy").format(expiry);
alertDialog.setMessage(date +
"\n" + J.getJSONArray("weather").getJSONObject(0).getString("description").toUpperCase(Locale.US) +
"\n" + "Maximum: " + J.getJSONObject("temp").getLong("max") + " ℃" +
"\n" + "Minimum: " + J.getJSONObject("temp").getLong("min") + " ℃" +
"\n" + "Morning: " + J.getJSONObject("temp").getLong("morn") + " ℃" +
"\n" + "At Night: " + J.getJSONObject("temp").getLong("night") + " ℃" +
"\n" + "Evening: " + J.getJSONObject("temp").getLong("eve") + " ℃" +
"\n" + "Humidity: " + J.getString("humidity") + "%" +
"\n" + "Pressure: " + J.getString("pressure") + " hPa" +
"\n" + "Wind: " + J.getString("speed") + "km/h");
alertDialog.show();
Log.i("Load" , "BFFK");}
catch (Exception e) {
Log.e("Error", "FO");
}
}
});
}
DateFormat df = DateFormat.getDateTimeInstance();
String updatedOn = df.format(new Date(json1.getLong("dt")*1000));
updatedField.setText("Last update: " + updatedOn);
int deg = json1.getJSONObject("wind").getInt("deg");
if (deg < 90)
directionView.setText(getActivity().getString(R.string.top_right));
else if (deg == 90)
directionView.setText(getActivity().getString(R.string.right));
else if (deg < 180)
directionView.setText(getActivity().getString(R.string.bottom_right));
else if (deg == 180)
directionView.setText(getActivity().getString(R.string.down));
else if (deg < 270)
directionView.setText(getActivity().getString(R.string.bottom_left));
else if (deg == 270)
directionView.setText(getActivity().getString(R.string.left));
else
directionView.setText(getActivity().getString(R.string.top_left));
setWeatherIcon(json1.getJSONArray("weather").getJSONObject(0).getInt("id"),10);
humidityView.setText("HUMIDITY:\n" + json1.getJSONObject("main").getInt("humidity") + "%");
Log.i("Humidity Loaded" , "Done");
windView.setText("WIND:\n" + json1.getJSONObject("wind").getDouble("speed") + "km/h");
Log.i("Wind Loaded" , "Done");
Log.i("10" , "Weather Icon 11 Set");
button.setOnClickListener(new View.OnClickListener() {
public void onClick (View v)
{
Units(json1);
}
});
weatherIcon[10].setOnClickListener(new View.OnClickListener()
{
public void onClick (View v)
{
AlertDialog alertDialog = new AlertDialog.Builder(getActivity()).create(); //Read Update
alertDialog.setTitle("Weather Information");
try{
String d1 = new java.text.SimpleDateFormat("hh:mm:ss a").format(new Date(json1.getJSONObject("sys").getLong("sunrise")*1000));
String d2 = new java.text.SimpleDateFormat("hh:mm:ss a").format(new Date(json1.getJSONObject("sys").getLong("sunset")*1000));
alertDialog.setMessage(json1.getJSONArray("weather").getJSONObject(0).getString("description").toUpperCase(Locale.US) +
"\n" + "TEMPERATURE :\t " + json1.getJSONObject("main").getInt("temp") + " ℃" +
"\n" + "Maximum:\t " + json1.getJSONObject("main").getDouble("temp_max") + " ℃" +
"\n" + "Minimum:\t " + json1.getJSONObject("main").getDouble("temp_min") + " ℃" +
"\n" + "Humidity:\t " + json1.getJSONObject("main").getString("humidity") + "%" +
"\n" + "Pressure:\t " + json1.getJSONObject("main").getString("pressure") + " hPa" +
"\n" + "Wind:\t " + json1.getJSONObject("wind").getString("speed") + "km/h" +
"\n" + "Sunrise:\t " + d1 +
"\n" + "Sunset:\t " + d2);
alertDialog.show();
Log.i("Load" , "BFFK");}
catch (Exception e) {
Log.e("Error", "FO");
}
}
});
button.setText(Integer.toString(a) + "°C");
button.setVisibility(View.VISIBLE);
}catch(Exception e){
Log.e("SimpleWeather", "One or more fields not found in the JSON data");
}
}

public WeatherFragment(){
handler = new Handler();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_weather, container, false);
cityField = (TextView)rootView.findViewById(R.id.city_field);
updatedField = (TextView)rootView.findViewById(R.id.updated_field);
humidityView = (TextView) rootView.findViewById(R.id.humidity_view);
windView = (TextView) rootView.findViewById(R.id.wind_view);
directionView = (TextView)rootView.findViewById(R.id.direction_view);
directionView.setTypeface(weatherFont);
dailyView = (TextView)rootView.findViewById(R.id.daily_view);
dailyView.setText("DAILY");
button = (Button)rootView.findViewById(R.id.button1);
button.setText("°C");
for (int i = 0; i < 11; ++i)
{
String f = "details_view" + (i + 1) , g = "weather_icon" + (i + 1);
if (i != 10) {
int resID = getResources().getIdentifier(f, "id", getContext().getPackageName());
detailsField[i] = (TextView) rootView.findViewById(resID);
}
int resIDI = getResources().getIdentifier(g, "id" , getContext().getPackageName());
weatherIcon[i] = (TextView)rootView.findViewById(resIDI);
weatherIcon[i].setTypeface(weatherFont);
}
return rootView;
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
weatherFont = Typeface.createFromAsset(getActivity().getAssets(), "fonts/weather.ttf");
updateWeatherData(new CityPreference(getActivity()).getCity());
}

private void setWeatherIcon(int id , int i){
String icon = "";
switch(id) {
case 501 : icon = getActivity().getString(R.string.weather_drizzle);
break;
case 500 : icon = getActivity().getString(R.string.weather_drizzle);
break;
case 502 : icon = getActivity().getString(R.string.weather_rainy);
break;
case 503 : icon = getActivity().getString(R.string.weather_rainy);
break;
case 504 : icon = getActivity().getString(R.string.weather_rainy);
break;
case 511 : icon = getActivity().getString(R.string.weather_rain_wind);
break;
case 520 : icon = getActivity().getString(R.string.weather_shower_rain);
break;
case 521 : icon = getActivity().getString(R.string.weather_drizzle);
break;
case 522 : icon = getActivity().getString(R.string.weather_thunder);
break;
case 531 : icon = getActivity().getString(R.string.weather_thunder);
break;
case 200 : icon = getActivity().getString(R.string.weather_thunder);
break;
case 201 : icon = getActivity().getString(R.string.weather_thunder);
break;
case 202 : icon = getActivity().getString(R.string.weather_thunder);
break;
case 210 : icon = getActivity().getString(R.string.weather_thunder);
break;
case 211 : icon = getActivity().getString(R.string.weather_thunder);
break;
case 212 : icon = getActivity().getString(R.string.weather_thunder);
break;
case 221 : icon = getActivity().getString(R.string.weather_thunder);
break;
case 230 : icon = getActivity().getString(R.string.weather_thunder);
break;
case 231 : icon = getActivity().getString(R.string.weather_thunder);
break;
case 232 : icon = getActivity().getString(R.string.weather_thunder);
break;
case 300 : icon = getActivity().getString(R.string.weather_shower_rain);
break;
case 301 : icon = getActivity().getString(R.string.weather_shower_rain);
break;
case 302 : icon = getActivity().getString(R.string.weather_heavy_drizzle);
break;
case 310 : icon = getActivity().getString(R.string.weather_shower_rain);
break;
case 311 : icon = getActivity().getString(R.string.weather_shower_rain);
break;
case 312 : icon = getActivity().getString(R.string.weather_heavy_drizzle);
break;
case 313 : icon = getActivity().getString(R.string.weather_rain_drizzle);
break;
case 314 : icon = getActivity().getString(R.string.weather_heavy_drizzle);
break;
case 321 : icon = getActivity().getString(R.string.weather_heavy_drizzle);
break;
case 600 : icon = getActivity().getString(R.string.weather_snowy);
break;
case 601 : icon = getActivity().getString(R.string.weather_snowy);
break;
case 602 : icon = getActivity().getString(R.string.weather_heavy_snow);
break;
case 611 : icon = getActivity().getString(R.string.weather_sleet);
break;
case 612 : icon = getActivity().getString(R.string.weather_heavy_snow);
break;
case 903 :
case 615 : icon = getActivity().getString(R.string.weather_snowy);
break;
case 616 : icon = getActivity().getString(R.string.weather_snowy);
break;
case 620 : icon = getActivity().getString(R.string.weather_snowy);
break;
case 621 : icon = getActivity().getString(R.string.weather_snowy);
break;
case 622 : icon = getActivity().getString(R.string.weather_snowy);
break;
case 701 :
case 702 :
case 721 : icon = getActivity().getString(R.string.weather_smoke);
break;
case 751 :
case 761 :
case 731 : icon = getActivity().getString(R.string.weather_dust);
break;
case 741 : icon = getActivity().getString(R.string.weather_foggy);
break;
case 762 : icon = getActivity().getString(R.string.weather_volcano);
break;
case 771 :
case 900 :
case 781 : icon = getActivity().getString(R.string.weather_tornado);
break;
case 904 : icon = getActivity().getString(R.string.weather_sunny);
break;
case 800 : icon = getActivity().getString(R.string.weather_sunny);
break;
case 801 : icon = getActivity().getString(R.string.weather_cloudy);
break;
case 802 : icon = getActivity().getString(R.string.weather_cloudy);
break;
case 803 : icon = getActivity().getString(R.string.weather_cloudy);
break;
case 804 : icon = getActivity().getString(R.string.weather_cloudy);
break;
case 901 : icon = getActivity().getString(R.string.weather_storm);
break;
case 902 : icon = getActivity().getString(R.string.weather_hurricane);
break;
}
Log.i(Integer.toString(id) , Integer.toString(i));
weatherIcon[i].setText(icon);
}
}

3. CityPreference.java

package com.a5corp.weather;

import android.app.Activity;
import android.content.SharedPreferences;

public class CityPreference {

SharedPreferences prefs;

public CityPreference(Activity activity){
prefs = activity.getPreferences(Activity.MODE_PRIVATE);
}

// If the user has not chosen a city yet, return
// Sydney as the default city
String getCity(){
return prefs.getString("city", "Sydney");
}

void setCity(String city) {
prefs.edit().putString("city", city).commit();
}

}

4. RemoteFetch.java

package com.a5corp.weather;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.location.Location;

public class RemoteFetch {

private static final String OPEN_WEATHER_MAP_FORECAST_API = "http://api.openweathermap.org/data/2.5/forecast/daily?q=%s&units=metric&cnt=10";
private static final String OPEN_WEATHER_MAP_DAILY_API = "http://api.openweathermap.org/data/2.5/weather?q=%s&units=metric";
private Location mLastLocation;

public static JSONObject[] getJSON(Context context, String city){
double Latitude , Longitude;
try {
URL day = new URL(String.format(OPEN_WEATHER_MAP_FORECAST_API, city));
URL fort = new URL(String.format(OPEN_WEATHER_MAP_DAILY_API, city));

HttpURLConnection connection0 = (HttpURLConnection)day.openConnection();
HttpURLConnection connection1 = (HttpURLConnection)fort.openConnection();
connection0.addRequestProperty("x-api-key", context.getString(R.string.open_weather_maps_app_id));
connection1.addRequestProperty("x-api-key", context.getString(R.string.open_weather_maps_app_id));

BufferedReader reader;
StringBuffer json = new StringBuffer(1024) , json1 = new StringBuffer(1024);

reader= new BufferedReader(new InputStreamReader(connection0.getInputStream()));
String tmp="";
while((tmp=reader.readLine())!=null)
json.append(tmp).append("\n");
reader.close();

reader = new BufferedReader(new InputStreamReader(connection1.getInputStream()));
String tmp1="";
while((tmp1=reader.readLine())!=null)
json1.append(tmp1).append("\n");
reader.close();

JSONObject data = new JSONObject(json.toString()) , data1 = new JSONObject(json1.toString());
double latitude = data1.getJSONObject("coord").getDouble("lat") , longitude = data1.getJSONObject("coord").getDouble("lon");


// This value will be 404 if the request was not
// successful
if(data.getInt("cod") != 200 || data1.getInt("cod") != 200){
return null;
}

JSONObject array[] = new JSONObject[2];
array[0] = data;
array[1] = data1;
return array;
}catch(Exception e){
return null;
}
}

}

5. fragment_weather.xml

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.a5corp.weather.WeatherActivity$PlaceholderFragment"
android:outlineProvider="bounds">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/city_field"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textColor="#FFFFFF"
android:ellipsize="end"
android:singleLine="true"
android:textSize="48sp" />

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1"
android:id="@+id/linearLayout2"
android:layout_below="@+id/daily_view"
android:layout_alignParentStart="true">

<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/horizontalScrollView">

<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent">

<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="5dp"
android:minWidth="85sp"
android:paddingRight="2dp"
android:layout_marginRight="8dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/weather_icon1"
android:textSize="70sp"
android:textColor="#FFFFFF"
android:textAlignment="textStart"
android:layout_gravity="center" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/details_view1"
android:textColor="#FFFFFF" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="5dp"
android:minWidth="85sp"
android:paddingRight="2dp"
android:layout_marginRight="8dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/weather_icon2"
android:textColor="#FFFFFF"
android:textSize="70sp"
android:textAlignment="textStart"
android:layout_gravity="center_horizontal" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/details_view2"
android:textColor="#FFFFFF" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="5dp"
android:minWidth="85sp"
android:paddingRight="2dp"
android:layout_marginRight="8dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/weather_icon3"
android:textColor="#FFFFFF"
android:textSize="70sp"
android:textAlignment="textStart"
android:layout_gravity="center_horizontal" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/details_view3"
android:textColor="#FFFFFF" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:minWidth="85sp"
android:layout_marginRight="8dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/weather_icon4"
android:layout_gravity="center_horizontal"
android:textAlignment="textStart"
android:textColor="#FFFFFF"
android:textSize="70sp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/details_view4"
android:textColor="#FFFFFF" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="false"
android:minWidth="85sp"
android:layout_marginRight="8dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/weather_icon5"
android:layout_gravity="center_horizontal"
android:textAlignment="textStart"
android:textColor="#FFFFFF"
android:textSize="70sp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/details_view5"
android:textColor="#FFFFFF" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="85sp"
android:layout_marginRight="8dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/weather_icon6"
android:layout_gravity="center_horizontal"
android:textAlignment="textStart"
android:textColor="#FFFFFF"
android:textSize="70sp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/details_view6"
android:textColor="#FFFFFF" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="85sp"
android:layout_marginRight="8dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/weather_icon7"
android:layout_gravity="center_horizontal"
android:textAlignment="textStart"
android:textColor="#FFFFFF"
android:textSize="70sp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/details_view7"
android:textColor="#FFFFFF" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="85sp"
android:layout_marginRight="8dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/weather_icon8"
android:layout_gravity="center_horizontal"
android:textAlignment="textStart"
android:textColor="#FFFFFF"
android:textSize="70sp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/details_view8"
android:textColor="#FFFFFF" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="85sp"
android:layout_marginRight="8dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/weather_icon9"
android:layout_gravity="center_horizontal"
android:textAlignment="textStart"
android:textColor="#FFFFFF"
android:textSize="70sp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/details_view9"
android:textColor="#FFFFFF" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="85sp"
android:layout_marginRight="8dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/weather_icon10"
android:layout_gravity="center_horizontal"
android:textAlignment="textStart"
android:textColor="#FFFFFF"
android:textSize="70sp" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/details_view10"
android:textColor="#FFFFFF" />
</LinearLayout>
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:id="@+id/updated_field"
android:layout_below="@+id/city_field"
android:layout_centerHorizontal="true"
android:textColor="#FFFFFF" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/weather_icon11"
android:textColor="#FFFFFF"
android:textSize="100sp"
android:layout_below="@+id/updated_field"
android:layout_centerHorizontal="true" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button"
android:visibility="invisible"
android:layout_below="@+id/weather_icon11"
android:layout_centerHorizontal="true" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/direction_view"
android:textColor="#FFFFFF"
android:textSize="40sp"
android:textStyle="bold"
android:layout_below="@+id/button"
android:layout_toRightOf="@+id/wind_view" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/wind_view"
android:textColor="#FFFFFF"
android:layout_below="@+id/button"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/button"
android:textAlignment="center"
android:layout_alignParentLeft="true" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/humidity_view"
android:layout_alignParentEnd="true"
android:layout_toEndOf="@+id/button"
android:textColor="#FFFFFF"
android:layout_below="@+id/button"
android:textAlignment="center"
android:layout_above="@+id/daily_view"
android:layout_alignParentRight="true" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/daily_view"
android:layout_below="@+id/wind_view"
android:layout_alignParentStart="true"
android:layout_marginTop="41dp"
android:textColor="#FFFFFF" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button1"
android:layout_above="@+id/direction_view"
android:layout_alignStart="@+id/button" />

</RelativeLayout>
</ScrollView>

6. activity_weather.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.a5corp.weather.WeatherActivity">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.a5corp.weather.WeatherActivity"
tools:ignore="MergeRootFrame"
android:background="#3F51B5" />

</android.support.design.widget.CoordinatorLayout>

0 Response to "How to create a Weather App on Android"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel