安卓专题

使用安卓Material Design开发一个天气应用

  这篇文章描述如何使用Android的material design guidelines设计一个天气应用. Material Design是一系列虚拟设计 UI交互 动作等的规则,这些规则帮助开发者能设计和创建一个安卓应用。

下面我们描述如何使用Weatherlib 作为天气库结合Material design规则创建一个天气应用. 我们开发的这个应用不仅支持Android 5 Lollipop(支持Material design ) ,而且要能支持Android之前版本如4.x Kitkat. 因此,我们需要引入appCompat v7 library帮助我们在以前版本实现Material Design

我们的应用有一个extended Toolbar 能够显示有关位置 当前天气 温度 湿度 风向 气压等信息,最后我们的节目类似下面这样:

material design android

 

安卓项目设置

首先我们要配置使用Weatherlib 和appCompat v7. 打开build.gradle配置文件,加入:

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.+'
compile 'com.mcxiaoke.volley:library:1.0.6@aar'
compile 'com.survivingwithandroid:weatherlib:1.5.3'
compile 'com.survivingwithandroid:weatherlib_volleyclient:1.5.3'
}

应用布局:Materail Design

正如之前提到,我们要使用 Toolbar,它是一个action bar,能给我们更多控制,区别于Action bar,它会紧紧和Actvitiy绑定, 一个Toolbar能放在View层次任何地方.

我们的布局layout划分主要下面几个区域:

  • Toolbar区域
  • 天气icon和温度
  • 其他天气数据

布局内容如下:

<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="match_parent"

    tools:context=".WeatherActivity"

    android:orientation="vertical">

 

    <android.support.v7.widget.Toolbar

        xmlns:app="http://schemas.android.com/apk/res-auto"

        android:id="@+id/my_toolbar"

        android:layout_height="128dp"

        app:popupTheme="@style/ActionBarPopupThemeOverlay"

        android:layout_width="match_parent"

        android:background="?attr/colorPrimary"

        android:paddingLeft="72dp"

        android:paddingBottom="16dp"

        android:gravity="bottom"

        app:titleTextAppearance="@style/Toolbartitle"

        app:subtitleTextAppearance="@style/ToolbarSubtitle"

        app:theme="@style/ThemeOverlay.AppCompat.Light"

        android:title="@string/location_placeholder"

        />

 

 ....

</RelativeLayout>

正如你看到我们使用Toolbar. 设置toolbar高度等于128dp, 我们使用初始颜色作为背景,初始颜色是在colors.xml定义. 你能按照 material design color guidelines 获得更多情况. 我们至少定义了三种不同颜色:

  • 初始颜色, 500
  • 初始黑颜色, identified by 700
  • 强调颜色用于初始动作按钮。

我们的toolbar背景颜色是设置为初始颜色

<resources>

    <color name="primaryColor_500">#03a9f4</color>

    <color name="primaryDarkColor_700">#0288d1</color>

    ....

</resources>

左内填充和底部填充工具栏定义都是根据要求设置。最后我们添加菜单项用于操作栏。主要的结果如下所示:

 

查询城市

我们使用popup弹出窗口让用户输入地理位置,弹窗很简单,它是使用 EditText ,可以输入数据和简单的ListView来显示在EditText输入的城市, 具体参考how to search a city in weatherlib,结果如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical" android:layout_width="match_parent"

    android:layout_height="match_parent"

   >

 

    <TextView

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="@string/dialog.city.header"

        style="@style/Theme.AppCompat.Dialog"/>

 

    <TextView

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_marginTop="8sp"

        android:text="@string/dialog.city.pattern"/>

 

    <EditText

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_marginTop="8dp"

        android:id="@+id/ptnEdit"/>

 

    <ListView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:id="@+id/cityList"

        android:clickable="true"/>

 

</LinearLayout>

下面代码创建和处理对话:

private Dialog createDialog() {

    AlertDialog.Builder builder = new AlertDialog.Builder(this);

    LayoutInflater inflater = this.getLayoutInflater();

    View v = inflater.inflate(R.layout.select_city_dialog, null);

    builder.setView(v);

 

    EditText et = (EditText) v.findViewById(R.id.ptnEdit);

    ....

    et.addTextChangedListener(new TextWatcher() {

         ....

        @Override

        public void onTextChanged(CharSequence s, int start, int before, int count) {

            if (count > 3) {

                // We start searching

                weatherclient.searchCity(s.toString(), new WeatherClient.CityEventListener() {

                    @Override

                    public void onCityListRetrieved(List<City> cities) {

                        CityAdapter ca = new CityAdapter(WeatherActivity.this, cities);

                        cityListView.setAdapter(ca);

 

                    }

 

                });

            }

        }

 

    });

    builder.setPositiveButton("Accept", new DialogInterface.OnClickListener() {

        @Override

        public void onClick(DialogInterface dialog, int which) {

            dialog.dismiss();

            // We update toolbar

            toolbar.setTitle(currentCity.getName() + "," + currentCity.getCountry());

            // Start getting weather

            getWeather();

        }

    });

 

    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

        @Override

        public void onClick(DialogInterface dialog, int which) {

            dialog.dismiss();

        }

    });

 

    return builder.create();

}

一个重要提示是在大约33行, 我们安卓用户选择的城市设置了toolbar标题,然后我们得到当前天气,这个代码运行结果如下:

 

我们通过WeatherLib获得天气情况,代码如下:

private void getWeather() {

    weatherclient.getCurrentCondition(new WeatherRequest(currentCity.getId()),

                         new WeatherClient.WeatherEventListener() {

                             @Override

                             public void onWeatherRetrieved(CurrentWeather currentWeather) {

                                 // We have the current weather now

                                 // Update subtitle toolbar

                                 toolbar.setSubtitle(currentWeather.weather.currentCondition.getDescr());

                                 tempView.setText(String.format("%.0f",currentWeather.weather.temperature.getTemp()));

                                 pressView.setText(String.valueOf(currentWeather.weather.currentCondition.getPressure()));

                                 windView.setText(String.valueOf(currentWeather.weather.wind.getSpeed()));

                                 humView.setText(String.valueOf(currentWeather.weather.currentCondition.getHumidity()));

                                 weatherIcon.setImageResource(WeatherIconMapper.getWeatherResource(currentWeather.weather.currentCondition.getIcon(), currentWeather.weather.currentCondition.getWeatherId()));

 

                                setToolbarColor(currentWeather.weather.temperature.getTemp());

                             }

     ....

}

你可以在8行左右注意到我们根据当前的天气设置工具栏字幕显示,在第15行我们根据当前温度改变工具栏的颜色。将工具栏背景颜色更改为我们Material Design指南中所示的原色。

 

 

本案例源码下载