material-ui_使用Material Design开发android weather app

material-ui

material-ui

这篇文章介绍了如何使用材料设计指南来创建天气应用。 材质设计是一组视觉设计,UI交互,动作等规则。 这些规则可帮助开发人员设计和创建Android应用。

这篇文章想描述我们如何使用Weatherlib作为天气层和Material设计规则来创建天气应用。 我们不仅要为原生支持Material Design的Android 5 Lollipop开发此应用,还希望支持4.x Kitkat之类的Android早期版本。 因此,我们将引入appCompat v7库,即使在先前的Android版本中,该也可以帮助我们实现Material Design。

我们想编写一个具有扩展工具栏的应用程序,其中包含有关位置和当前天气的一些信息以及有关温度,天气图标,湿度,风和压力的一些基本天气信息。 最后,我们将得到如下图所示的图片:

android_material_weather_1

Android项目设置

我们要做的第一件事是配置项目,以便我们可以使用Weatherlib,尤其是appCompat v7。 我们可以打开build.graddle并添加以下行:

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'
}

现在我们已经正确设置了项目,我们可以开始定义应用布局。

应用布局:材质设计

如前所述,我们想在扩展工具栏上使用工具工具栏是操作栏的综合,可以给我们更多的控制权。 与紧密绑定到Actvitiy的操作栏不同,工具栏可以放置在View层次结构内的任何位置。

因此,我们的布局将分为三个主要区域:

  • 工具栏区域
  • 天气图标和温度
  • 其他天气数据

布局如下图所示:

<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>

如您所见,我们使用了工具栏。 如指南中所述,我们将工具栏的高度设置为等于128dp,此外,我们使用原色作为背景。 原色在colors.xml中定义。 您可以参考材料设计颜色准则以获取更多信息。 我们应该定义至少三种不同的颜色:

  • 原色,由500标识
  • 700标识的主要深色
  • 应当是主要操作按钮等的强调颜色

工具栏的背景色设置为原色。

<resources>
    <color name="primaryColor_500">#03a9f4</color>
    <color name="primaryDarkColor_700">#0288d1</color>
    ....
</resources>

此外,工具栏内的左侧填充和底部填充是根据准则定义的。 最后,我们添加菜单项,就像使用操作栏一样。 主要结果如下所示:

android_material_weather

如您所见,工具栏的背景等于原色。

搜索城市:带有材料设计的弹出窗口

我们可以使用弹出窗口让用户输入位置。 弹出窗口非常简单,它由一个用于输入数据的EditText和一个简单的ListView组成,该ListView显示与插入EditText中的模式匹配的城市。 我不会介绍如何在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行,根据用户选择的城市设置工具栏标题,然后获取当前天气。 这段代码的结果如下所示:

android_material_weather_popup

天气库:天气

要获取当前天气,我们使用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行,我们根据当前温度更改工具栏颜色。 作为工具栏的背景色,我们使用了准则中显示的原色。

android_material_weather_moscow
android_material_weather_miami

android_material_weather_victoria
android_material_weather_russia

翻译自: https://www.javacodegeeks.com/2014/11/develop-android-weather-app-with-material-design.html

material-ui

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Material-UI的Select组件中使用树结构,你可以使用Recursive Tree组件。以下是一个示例代码: ```jsx import React from 'react'; import PropTypes from 'prop-types'; import { makeStyles } from '@material-ui/core/styles'; import TreeView from '@material-ui/lab/TreeView'; import TreeItem from '@material-ui/lab/TreeItem'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import ChevronRightIcon from '@material-ui/icons/ChevronRight'; import FormControl from '@material-ui/core/FormControl'; import InputLabel from '@material-ui/core/InputLabel'; import Select from '@material-ui/core/Select'; const data = { id: 'root', name: 'Parent Node', children: [ { id: '1', name: 'Child Node 1', children: [ { id: '2', name: 'Subchild Node 1', }, { id: '3', name: 'Subchild Node 2', }, ], }, { id: '4', name: 'Child Node 2', children: [ { id: '5', name: 'Subchild Node 3', }, { id: '6', name: 'Subchild Node 4', }, ], }, ], }; const useStyles = makeStyles({ root: { height: 240, flexGrow: 1, maxWidth: 400, }, }); function renderTreeItems(items) { return ( <> {items.map((item) => ( <TreeItem key={item.id} nodeId={item.id} label={item.name}> {Array.isArray(item.children) ? renderTreeItems(item.children) : null} </TreeItem> ))} </> ); } function RecursiveTreeView(props) { const classes = useStyles(); const { onChange, value } = props; const handleChange = (event) => { onChange(event.target.value); }; return ( <FormControl className={classes.formControl}> <InputLabel htmlFor="tree-select">Select</InputLabel> <Select native value={value} onChange={handleChange} inputProps={{ name: 'tree-select', id: 'tree-select', }} > <option value="" /> {renderTreeItems([data])} </Select> </FormControl> ); } RecursiveTreeView.propTypes = { onChange: PropTypes.func.isRequired, value: PropTypes.string.isRequired, }; export default function SelectWithTree() { const [value, setValue] = React.useState(''); const handleChange = (newValue) => { setValue(newValue); }; return ( <RecursiveTreeView onChange={handleChange} value={value} /> ); } ``` 在这个示例中,我们首先定义了一个树形数据结构,然后使用`renderTreeItems()`函数递归渲染树形结构。最后,在`RecursiveTreeView`组件中,我们使用`FormControl`和`Select`组件来显示树形结构,并在选择时触发`onChange`事件。你可以根据自己的需要来修改这个示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值