android studio_android studio安装 - CSDN
android studio 订阅
Android Studio 是谷歌推出的一个Android集成开发工具,基于IntelliJ IDEA. 类似 Eclipse ADT,Android Studio 提供了集成的 Android 开发工具用于开发和调试。 展开全文
Android Studio 是谷歌推出的一个Android集成开发工具,基于IntelliJ IDEA. 类似 Eclipse ADT,Android Studio 提供了集成的 Android 开发工具用于开发和调试。
信息
软件版本
4.0(正式版) [1]
软件平台
Linux,macOS,Windows
软件语言
Java,Kotlin
软件大小
923M(包含 Android SDK)
开发商
Google
软件授权
Apache许可证2.0
软件名称
Android Studio
作    用
android开发
Android Studio架构组成
在IDEA的基础上,Android Studio 提供 [2]  :
收起全文
  • android studio安装教程

    2020-07-28 17:02:18
    百度搜索Android studio,或者直接输入http://www.android-studio.org进入这个页面 根据这个下载相应的安装包或者压缩包。 这里演示安装64位的android studio 下载完成后直接双击安装包,就会出来...

    百度搜索Android studio,或者直接输入http://www.android-studio.org进入这个页面

     

     

     

    根据这个下载相应的安装包或者压缩包。

     

     

    这里演示安装64位的android studio

    下载完成后直接双击安装包,就会出来下面这个界面

    点击Next

     

    点击Next

     

     

    点击Next

     

     

    点击install

     

     

    等待进度条走完

     

     

    点击Next

     

     

    点击finish

     

     

    选择第二个,点击ok

     

     

    两个都可以,我点击Don’t  send

     

     

    点击Cancel

     

     

    点击Next

     

     

    选择第一个,点击Next

     

     

    选择你想要的主题颜色,点击Next

     

     

    点击Finish

     

     

    进度条走完后点击Finish

     

     

    点击第一个新建项目

     

     

    点击Next

     

     

    点击Finish

     

     

    这个有可能下载不下来

     

     

     

    解决办法

    进入https://services.gradle.org/distributions/下载对应版本的gradle

    把Android stutid关掉

    进入到C盘C:\Users\ASUS\.gradle\wrapper\dists\gradle-5.1.1-all\97z1ksx6lirer3kbvdnh7jtjg把里面的文删掉(是哪个版本的gradle就选择哪个版本的文件夹)

    把下载下来的gradle放到这个文件夹(不要解压gradle,直接放进去

    打开Android stutio

    点击这个进行重构

    有可能因为网络问题,项目构建失败,请看教程的最下面的解决方法

    这个变成绿色就说明项目创建成功,可以运行了

     

     

    点击这个新建模拟器

     

     

     

     

    选择完之后点击Next

     

     

    点击Download下载你想要的系统,下载完之后选中,点击Next

     

     

    点击Finish

     

     

    启动

     

     

    点击之后选择手机点ok就会运行到模拟器上。

     

     

    运行成功

     

    问题记录

    问题1:

    日期2020/3/3

    错误提示Cause:unable to find valid certification path to requested target

    原因:网络问题,目标服务器在国外,有时会出现下载不下来的情况

    解决办法:在gradle.build里面把原来的google()和jcenter()方法注释掉添加阿里云的镜像

    maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
    maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/' }
    maven{ url 'http://maven.aliyun.com/nexus/content/repositories/jcenter'}

    示例:

    添加完之后一定要点右上角Sync now,如果出现错误继续点重构,不行就多点几次。

     

     

    展开全文
  • 一、功能需求 1、罗列全国的省、市、县 2、查看全国任意城市的天气情况 3、自由切换城市,查看异地城市的天气情况 4、手动更新与后台自动更新天气的功能 二、可行性分析: 1、需要用到的技术有:UI、网络、数据存储...

    参考文献:第一行代码(第二版),郭霖
    源码地址:https://github.com/2066972218/coolweather/commits/master

    一、功能需求
    1、罗列全国的省、市、县
    2、查看全国任意城市的天气情况
    3、自由切换城市,查看异地城市的天气情况
    4、手动更新与后台自动更新天气的功能

    二、可行性分析:
    1、需要用到的技术有:UI、网络、数据存储、服务
    2、天气信息来源:和风天气,有3000+次/天免费数据获取
    3、架设服务器用于提供全国的省市县的数据信息

    三、全国地区信息获取

    1、访问 http://guolin.tech/api/china 得到以下全国地区数据,其包括了中国所有的省份以及省份的id:在这里插入图片描述
    这是一个JSON格式的数组,在网址后加相应城市的id可以得到该省份城市下的所有市级城市,如:
    http://guolin.tech/api/china/30
    在这里插入图片描述在网址后继续键入id,可以得到该市级下的县级城市:
    如:http://guolin.tech/api/china/30/304
    在这里插入图片描述
    可以看到每一个县级城市都有一个weather_id,我们可以通过这个id去访问和风天气的接口,从而过去该地区的的天气情况。

    2、使用和风天气的接口
    注册账号:http://guolin.tech/api/weather/register
    选择免费用户,注册成功后,去邮箱激活,在这里插入图片描述之后登陆该账号,https://console.heweather.com/ 查看API接口说明文档。

    3、Git时间
    https://github.com/ 为GitHub官网,注册登陆,点击start a project~输入Coolweather~选择Android项目类型的gitignore文件和Apach License2.0作为天气的开源协议
    在这里插入图片描述
    创建成功后出现以下界面,其中README.md为版本库主页说明,点击Clone or download按钮,将该复制到剪贴板:在这里插入图片描述
    版本库主页为:https://github.com/2066972218/coolweather

    在Android Studio中新建一个项目CoolWeather,然后将远程代码库克隆值本地,在Termiminal中输入
    git clone https://github.com/2066972218/coolweather.git,
    如图所示,说明克隆成功。
    在这里插入图片描述
    在Android Studio中把项目文件下的CoolWeather/coolweather的所有文件,包括隐藏的.git文件剪切(mv .git .. /)到CoolWeather文件目录下。

    接下来通过在Termiminal中输入一下代码,将CoolWeather项目中的文件上传到Git版本控制中。
    git add .
    git commit -m "First commit"
    git push origin master
    在执行最后一条语句时发生一个错误,借助博客链接:
    https://blog.csdn.net/jingfengvae/article/details/72859130 解决。
    提交成功后,看版本库已经更新成功,也就是我们的代码已经提交值远程代码库了,如图:
    在这里插入图片描述
    也就是我们该项目的版本控制Git创建好了,下面我们来继续项目编码。

    4、数据库的创建与配置
    创建4个包db、gson、service、util,db包用于存放数据库模型的代码、gson用于存放GSON模型的相关代码,util包用于存储工具相关代码。在这里插入图片描述
    为简化数据库的操作我们采用LitePal来管理项目的数据库,先添加好一下我们后续需要用到的依赖闭包:

        //用于对数据库进行操作
        implementation 'org.litepal.android:core:1.4.1'
        //用于进行网络请求
        implementation 'com.squareup.okhttp3:okhttp:3.4.1'
        //用于JSON解析
        implementation 'com.google.code.gson:gson:2.7'
        //用于加载和展示图片
        implementation 'com.github.bumptech.glide:glide:3.7.0'
    

    在db包下我们创建三张表(实体类):province、city、county分别存放省市县的数据信息。
    province实体类如下:

    public class Province extends DataSupport {
       private int id;//每个实体类都有的字段
       private String provinceName;//记录省份名字
       private int provinceCode;//记录省的代号
       public int getId() {
           return id;
       }
       public void setId(int id) {
           this.id = id;
       }
       public String getProvinceName() {
           return provinceName;
       }
       public void setProvinceName(String provinceName) {
           this.provinceName = provinceName;
       }
       public int getProvinceCode() {
           return provinceCode;
       }
       public void setProvinceCode(int provinceCode) {
           this.provinceCode = provinceCode;
       }
    }
    

    同理,新建的City类,代码如下:

    public class City extends DataSupport {
        private int id;   //每一个实体类都有一个id
        private String cityName;  //记录市名称
        private int cityCode;   //几率市的代码
        private int provinceCode;  //记录该市的上级省级代码
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getCityName() {
            return cityName;
        }
        public void setCityName(String cityName) {
            this.cityName = cityName;
        }
        public int getCityCode() {
            return cityCode;
        }
        public void setCityCode(int cityCode) {
            this.cityCode = cityCode;
        }
        public int getProvinceCode() {
            return provinceCode;
        }
        public void setProvinceCode(int provinceCode) {
            this.provinceCode = provinceCode;
        }
    }
    

    同理,记录代表区县的County类,如下:

    public class County extends DataSupport {
        private int id;//每一个实体类都需有一个id
        private String countyName; //记录区县名称
        private int countyCode;//记录区县代码
        private int weatherId;//记录该区县的天气信息
        private int cityId;//该区县所属的市级代码
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getCountyName() {
            return countyName;
        }
        public void setCountyName(String countyName) {
            this.countyName = countyName;
        }
        public int getCountyCode() {
            return countyCode;
        }
        public void setCountyCode(int countyCode) {
            this.countyCode = countyCode;
        }
        public int getWeatherId() {
            return weatherId;
        }
        public void setWeatherId(int weatherId) {
            this.weatherId = weatherId;
        }
        public int getCityId() {
            return cityId;
        }
        public void setCityId(int cityId) {
            this.cityId = cityId;
        }
    }
    

    以上我们也就完成这三个实体类的内容,接下配置数据库

    在main目录下创建一个assets的的路径,在该路径下创建一个litepal.xml文件,在该文件输入:

    <?xml version="1.0" encoding="utf-8"?>
    <litepal>
        <dbname value = "cool_weather"/>    //指定数据库名
        <version value = "1"/>     //数据库版本号
        <!--将三个实体类添加到映射列表中-->
        <list>
            <mapping class = "com.example.coolweather.db.Province"/>
            <mapping class = "com.example.coolweather.db.City"/>
            <mapping class = "com.example.coolweather.db.County"/>
        </list>
    </litepal>
    

    最后修改AndroidManifest.xml中添加以下代码:

     <application
        android:usesCleartextTraffic="true"
        android:name="org.litepal.LitePalApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        </application>
    

    现在数据库配置完毕了,数据库和表会在首次执行自行创建,现在我们将这一阶段的代码提交到版本控制中,即在Terrminal中输入如下:
    git add .
    git commit -m "加入创建数据库和表的各项配置"
    git push origin master

    5、加载全国省市县的所有数据
    从上面我们知道全国的省市县信息我们都是从服务器中获取的,所有这里我们需要与服务其进行交互。在util中创建一个HttpUtil类。

    public class HttpUtil {
        public static void sendOKHttpRequest(String adress, okhttp3.Callback callback){
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder().url(adress).build();
            client.newCall(request).enqueue(callback);
        }
    }
    

    根据三的全国地区信息知道我们获取的信息为JSON格式的,需要解析后才能存入数据库,在util文件中新建一个Utility工具类来解析和处理这些信息。如下:

    public class Utility {
        /*解析和处理服务器返回的省级数据 */
        public static boolean handleProvinceResponse(String response){
            if (!TextUtils.isEmpty(response)){  //如果返回的数据不为空
                try {
                    //将所有的省级数据解析出来,并组装成实体类对像
                    JSONArray allProvinces = new JSONArray(response);
                    for (int i=0;i<allProvinces.length();i++){
                        JSONObject provinceObject = allProvinces.getJSONObject(i);
                        Province province = new Province();
                        province.setProvinceName(provinceObject.getString("name"));
                        province.setProvinceCode(provinceObject.getInt("id"));
                        //将该实体类对象存入数据库
                        province.save();
                    }
                    return true;//解析成功
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            return false;//解析失败
        }
    
        /*解析和处理服务器返回的市级数据 */
        public static boolean handleCityResponse(String response,int provinceId){
            if (!TextUtils.isEmpty(response)){
                try {
                    JSONArray allCities = new JSONArray(response);
                    for (int i=0;i<allCities.length();i++){
                        JSONObject cityObject = allCities.getJSONObject(i);
                        City city = new City();
                        city.setCityCode(cityObject.getInt("id"));
                        city.setCityName(cityObject.getString("name"));
                        city.setProvinceCode(provinceId);  //所属的省级代号
                        city.save();
                    }
                    return true;
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            return false;
        }
        /*解析和处理服务器返回的县级数据 */
        public static boolean handleCountyResponse(String response,int cityId){
            if (!TextUtils.isEmpty(response)){
                try {
                    JSONArray allCounties = new JSONArray(response);
                    for (int i=0;i<allCounties.length();i++){
                        JSONObject countyObject = allCounties.getJSONObject(i);
                        County county = new County();
                        county.setCountyName(countyObject.getString("name"));
                        //县级天气信息
                    county.setWeatherId(countyObject.getString("weather_id"));
                        //所属的市级代号
                        county.setCityId(cityId);
                        county.save();
                    }
                    return true;
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            return false;
        }
    }
    

    解析出省市县的数据后,现在我们来编写界面UI,为后面我们布局复用,因为我们不实用原生的ActionBar
    er,故我们在style.xml将其设置为

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    

    我们将界面写在碎片里,新建布局文件choose_area.xml,如下:

    <?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="match_parent"
        android:orientation="vertical"
        android:background="#fff">
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/colorPrimary">
    
            <TextView
                android:id="@+id/title_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:textColor="#fff"
                android:textSize="20sp"/>
            <Button
                android:id="@+id/back_button"
                android:layout_width="25dp"
                android:layout_height="25dp"
                android:layout_marginLeft="10dp"
                android:layout_alignParentLeft="true"
                android:layout_centerVertical="true"
                android:background="@drawable/ic_back" />        
        </RelativeLayout>
        <ListView
            android:id="@+id/list_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
    

    创建一个AreaFragment继承自Fragment,在其中编写遍历全国的省市县数据,通过从数据库获取和网络获取两种方式来加载全国省市县数据,逻辑代码如下:

    public class ChooseAreaFragment extends Fragment {
    
        public static final int LEVEL_PROVINCE=0;
        public static final int LEVEL_CITY=1;
        public static final int LEVEL_COUNTY=2;
    
        private ProgressDialog progressDialog;
    
        private TextView titleText;
    
        private Button backButton;
    
        private ListView listView;
    
        private ArrayAdapter<String> adapter;
    
        private List<String> dataList = new ArrayList<>();
    
        private int currentLevel;  //当前被选中的级别
        private Province selectedProvince;//被选中的省份
        private City selectedCity;//被选中的城市
    
        private List<Province> provinceList;//省列表
        private List<City> cityList;//市列表
        private List<County> countyList ;//县列表
    
        /*获取控件实例id*/
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                                 @Nullable Bundle savedInstanceState) {
            Log.d("ChooseAreaFragment","onCreateView");
            View view = inflater.inflate(R.layout.choose_area,container,false);
            titleText = (TextView)view.findViewById(R.id.title_text);  //获取标题栏文本id
            backButton = (Button) view.findViewById(R.id.back_button);  //获取标题栏id
            listView = (ListView)view.findViewById(R.id.list_view);    //获取Item列表id
            //获取ArrayAdapter对象
            adapter =new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1, dataList);
            listView.setAdapter(adapter);//设置并初始化适配器
            return view;//将视图返回
        }
     
        /*点击事件集合*/
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            Log.d("ChooseAreaFragment","onActivityCreated");
            super.onActivityCreated(savedInstanceState);
            //列表任意一栏被点击,则...
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Log.d("ChooseAreaFragment","列表被点了的...");
                    if (currentLevel == LEVEL_PROVINCE){   //当前选中的级别为省份时
                        selectedProvince = provinceList.get(position);  //当前点击为选中状态
                        queryCities();//查询市的方法
                    }
                    else if (currentLevel == LEVEL_CITY){
                        selectedCity = cityList.get(position);
                        queryCounties();
                    }
                }
            });
            backButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (currentLevel == LEVEL_COUNTY){
                        queryCities();
                    }
                    else if (currentLevel == LEVEL_CITY){
                        queryProvinces();
                    }
                }
            });
            queryProvinces();
        }
    
        private void queryCities() {
            titleText.setText(selectedProvince.getProvinceName());  //设置市的标题内容
            backButton.setVisibility(View.VISIBLE);  //设置返回按钮可见
            //查询被选中的省份城市的市区
            cityList = DataSupport.where("provinceid=?",String.valueOf(selectedProvince.
                            getId())).find(City.class);
            Log.d("ChooseAreaFragment","市级");
            if (cityList.size()>0){ //如果省列表不为空,则...
                dataList.clear();
                for (City city:cityList){ //遍历每一份省的市级城市
                    dataList.add(city.getCityName()); //添加到数据列表中
                }
                adapter.notifyDataSetChanged();//通知适配器数据更新了
                listView.setSelection(0);
                currentLevel = LEVEL_CITY;
            }
            else{
                int provinceCode = selectedProvince.getProvinceCode();  //获取被选取省级代码
                String address = "http://guolin.tech/api/china/"+provinceCode;//获取被选取地区的网络地址
                Log.d("ChooseAreaFragment","准备在网络中获取地址信息");
                queryFromServer(address,"city");   // 在网络中查询
            }
        }
        /*根据传入的地址和类型从服务器查询省市县数据*/
        private void queryFromServer(String adress, final String type) {
            showProgressDialog();
            //   发送一条网络请求
            HttpUtil.sendOKHttpRequest(adress, new Callback() {
    
                //请求加载失败
                @Override
                public void onFailure(Call call, IOException e) {
                    //通过runOnUiThread方法回到主线程逻辑
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            closeProgressDialog();
                            Toast.makeText(getContext(),"加载失败",Toast.LENGTH_SHORT).show();
                        }
                    });
                }
    
                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    Log.d("ChooseAreaFragment","加载地区信息...");
                    String responseText = response.body().string();
                    boolean result = false;
                    if ("province".equals(type)){
                        result = Utility.handleProvinceResponse(responseText);
                    }
                    else if ("city".equals(type)){
                        result = Utility.handleCityResponse(responseText,selectedProvince.getId());
                    }
                    else if ("county".equals(type)){
                        result = Utility.handleCountyResponse(responseText, selectedCity.getId());
                    }
                    if (result)
                    {
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Log.d("ChooseAreaFragment","开启线程更新UI");
                                closeProgressDialog();
                                if ("province".equals(type)){
                                    queryProvinces();
                                }
                                else if ("city".equals(type)){
                                    queryCities();
                                }
                                else if ("county".equals(type)){
                                    queryCounties();
                                }
                            }
                        });
                    }
    
                    if ("city".equals(type)){
                        result = Utility.handleProvinceResponse(responseText);
                    }
                    if ("county".equals(type)){
                        result = Utility.handleProvinceResponse(responseText);
                    }
    
    
                }
            });
        }
    
        /*显示进度对话框*/
        private void showProgressDialog() {
            if (progressDialog==null){
                progressDialog = new ProgressDialog(getActivity());
                progressDialog.setMessage("正在加载...");
                progressDialog.setCanceledOnTouchOutside(false);
    
            }
            progressDialog.show();
        }
    
        private void queryCounties() {
            titleText.setText(selectedCity.getCityName());
            backButton.setVisibility(View.VISIBLE);
            countyList = DataSupport.where("cityid = ?", String.valueOf(selectedCity.getId())).find(County.class);
            if (countyList.size()>0){
                dataList.clear();
                for (County county:countyList){
                    dataList.add(county.getCountyName());
                }
                adapter.notifyDataSetChanged();
                listView.setSelection(0);
                currentLevel=LEVEL_COUNTY;
            }
            else {
                int provinceCode = selectedProvince.getProvinceCode();
                int cityCode = selectedCity.getCityCode();
                String address = "http://guolin.tech/api/china/"+provinceCode+"/"+cityCode;
                queryFromServer(address,"county");
            }
        }
    
        /*全国所有的省,优先查询数据库,如果没有再去服务器查询*/
        private void queryProvinces() {
            titleText.setText("中国");
            Log.d("ChooseAreaFragment","查询省中...");
            backButton.setVisibility(View.GONE);
            provinceList = DataSupport.findAll(Province.class);
            if (provinceList.size()>0){
                dataList.clear();
                for (Province province:provinceList){
                    dataList.add(province.getProvinceName());
                }
                adapter.notifyDataSetChanged();
                listView.setSelection(0);
                currentLevel = LEVEL_PROVINCE;
            }
            else {
                Log.d("ChooseAreaFragment","服务器查询省中...");
                String address = "http://guolin.tech/api/china";
                queryFromServer(address,"province");
            }
        }
        private void closeProgressDialog() {
            if (progressDialog!=null){
                progressDialog.dismiss();
            }
        }
    }
    

    接下来将碎片县市县碎片县市在主布局中,修改activity.xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout 
        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">
        <fragment
            android:id="@+id/choose_area_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:name = "com.example.coolweather.ChooseAreaFragment" />
    </FrameLayout>
    

    添加网络访问权限:

    <uses-permission android:name="android.permission.INTERNET"/>
    

    别忘了添加:

    android:usesCleartextTraffic="true"
    

    运行过程中出现一个错误为:

    no such column: provinceId (code 1): , while compiling: SELECT * FROM city WHERE provinceId

    说是在city中没有找到provinceId者一列的数据库,经分析为数据库在没有创建city列表前有创建国数据库,所有这里我们将litepal.xml中的版本号升级为2,即:

     <version value = "2"/>     //数据库版本号
    

    查看下运行图:
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
    第一部分也就完成了,将代码提交到远程仓库:

    CoolWeather apple$ git add .
    
    CoolWeather apple$ git commit -m "遍历中国省市县三级列表显示功能"
    
    CoolWeather apple$ git push origin master
    

    6、显示天气信息
    由于获取的天气信息较为复杂,我们采用GSON来获取天气信息。
    在gson包中建立一个Basic类,来显示城市的基础信息:

    public class Basic {
        @SerializedName("city")   //JSON字段和Java字段建立映射
        public String cityName;   //城市名
        @SerializedName("id")
        public String weather_id;  //天气情况
        public Update update;  
        public class Update {
            @SerializedName("loc")
            public String updateTime;   //天气更新时间
        }
    }
    

    同理,新建一个AQI类:

    public class AQI {
        public AQICity city;
        public class AQICity{
            public String aqi;
            public String pm25;
        }
    }
    

    新建一个Now类显示温度和天气情况:

    public class Now {
        @SerializedName("tmp")
        public String tempeture;
        @SerializedName("cond")
        public More more;
        private class More {
            @SerializedName("txt")
            public String info;
        }
    }
    

    新建一个Suggestion类来推荐日常活动:

    public class Suggestion {
        @SerializedName("comf")
        public Comfort comfort;   
        @SerializedName("cw")
        public  CarWash carWash;    
        public Sport sport;
        public class Comfort {
            @SerializedName("txt")
            public String info;
        }
        public class CarWash{
            @SerializedName("txt")
            public String info;
        }
        private class Sport {
            @SerializedName("txt")
            public String info;
        }
    }
    

    继续在gson包下新建一个Forecas的类开表示未来的天气情况,其包含的会是一个数组:

    public class Forecast {
        public String data;
        @SerializedName("tmp")
        public Temperature temperature;
        @SerializedName("cond")
        public More more;
        public class Temperature {
            public  String max;
            public String min;
        }
        private class More {
            @SerializedName("txt_d")
            public String info;
        }
    }
    

    新建一个总的实例类,在gson下的Weather类来引用刚创建的各个实体类:

    public class Weather {
       public String status;  //返回是否成功返回值
       public Basic basic;
       public Forecast forecast;
       public AQI aqi;
       public Now now;
       @SerializedName("daily_forecast")
       public List<Forecast> forecastList;  //解析出数组
    

    GSon所有的实体类都定义好后,下面来编写天气界面UI
    创建一个活动为WeatherActivity,布局指定为activity_weather.xml,这个界面我们用分模块来构建布局UI,后面在使用include来集成:
    首先建立一个title.xml作为头布局,在该头布局中放置两个TextView用于分别显示:城市名和显示更新事件,如下:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
       xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="?attr/actionBarSize">
       <TextView
           android:id="@+id/title_city"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_centerInParent="true"
           android:textColor="#fff"
           android:textSize="20sp"/>
       <TextView
           android:id="@+id/title_update_time"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_marginRight="10dp"
           android:layout_alignParentRight="true"
           android:layout_centerVertical="true"
           android:textColor="#fff"
           android:textSize="16sp"/>
    </RelativeLayout>
    

    在新建一个now.xml来显示天气信息,包括当前气温和天气概况,如下:

    <LinearLayout 
       xmlns:android="http://schemas.android.com/apk/res/android"
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="wrap_content">
       <!--显示当前气温-->
       <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content" 
           android:id="@+id/degree_text"
           android:layout_gravity="end"
           android:textSize="60sp"
           android:textColor="#fff"
           />
       <!--显示天气概况-->
       <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content" 
           android:id="@+id/weather_info_text"
           android:layout_gravity="end"
           android:textSize="20sp"
           android:textColor="#fff"/>
    </LinearLayout>
    

    在新建forecast.xml来显示未来几天的天气:

    <?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="vertical"
        android:layout_margin="15dp"
        android:background="#8000">
        <!--定义了一个标题-->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="15dp"
            android:layout_marginTop="15dp"
            android:text="预报"
            android:textColor="#fff"
            android:textSize="20sp"/>
        <!--未来几天天气信息的布局,需要根据服务器返回的数据在代码中动态添加-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:id="@+id/forecast_layout">
        </LinearLayout>
    </LinearLayout>
    

    在定义一个未来天气的子项布局forecast_item.xml,如下:

    <?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:layout_margin="15dp">
        <!--天气时间-->
        <TextView
            android:id="@+id/data_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="2"
            android:textColor="#fff"/>
        <!--天气概况-->
        <TextView
            android:id="@+id/info_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content" 
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:gravity="center"
            android:textColor="#fff"/>
        <!--最高温度-->
        <TextView
            android:id="@+id/max_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content" 
            android:layout_gravity="center"
            android:layout_weight="1"
            android:gravity="right"
            android:textColor="#fff"/>
        <!--最低气温-->
        <TextView
            android:id="@+id/min_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:gravity="right"
            android:textColor="#fff"/>   
    </LinearLayout>
    

    新建一个aqi.xml作为空气质量的布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:background="#8000">    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="15dp"
            android:layout_marginTop="15dp"
            android:text="空气质量"
            android:textColor="#fff"
            android:textSize="20sp"/>    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="15dp">
            <RelativeLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1">            
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:layout_centerInParent="true">
                    
                    <TextView
                        android:id="@+id/aqi_text"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:textColor="#fff"
                        android:textSize="40sp"/>
                    
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content" 
                        android:layout_gravity="center"
                        android:text="AQI指数"
                        android:textColor="#fff"/>
                </LinearLayout>
            </RelativeLayout>
            <RelativeLayout
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:layout_centerInParent="true">
    
                    <TextView
                        android:id="@+id/pm25_text"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:textColor="#fff"
                        android:textSize="40sp"/>
                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:text="PM2.5指数"
                        android:textColor="#fff"/>
                </LinearLayout>
            </RelativeLayout>
        </LinearLayout>
    </LinearLayout>
    

    在新建一个suggestion.xml来作为生活建立信息布局,如下:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        android:background="#8000">    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:layout_marginLeft="15dp"
            android:layout_marginTop="15dp"
            android:text="生活建议"
            android:textColor="#fff"
            android:textSize="20sp" />
        <!--舒适度-->
        <TextView
            android:id="@+id/comfort_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:textColor="#fff"/>
        <!--洗车指数-->
        <TextView
            android:id="@+id/car_wash_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:textColor="#fff"/>
        <!--运动建议-->
        <TextView
            android:id="@+id/sport_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="15dp"
            android:textColor="#fff"/>
    </LinearLayout>
    

    最后将以上编写的布局引入到activity_weather.xml中,如下:

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary">    
        <ScrollView
            android:id="@+id/weather_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="none"
            android:overScrollMode="never">        
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">            
                <include layout="@layout/title"/>            
                <include layout="@layout/now"/>         
                <include layout="@layout/forecast"/>
                <include layout="@layout/api"/>
                <include layout="@layout/suggestion"/>
            </LinearLayout>
        </ScrollView>
    </FrameLayout>
    

    以上天气UI我们就编写完毕了,看一下效果:
    在这里插入图片描述
    接下来,开始逻辑部分的实现,首先得在Utility类中添加解析天气JSON数据的方法:

     /*将返回的JSON数据解析成Weather实体类*/
        public static Weather handleWeatherResponse(String response){
            try {
                //通过JSONObject和JSONArray将天气数据中的主体内容解析出来
                JSONObject jsonObject = new JSONObject(response);   
                JSONArray jsonArray = jsonObject.getJSONArray("HeWeather");
                String weatherContent = jsonArray.getJSONObject(0).toString();
                //将JSON数据转换成Weather对象
                return new Gson().fromJson(weatherContent,Weather.class);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }
    

    接着,在WeatherActivity中去请求天气数据,以及将数据展示到界面上,记得key值需要自己去和风天气官网去获取,每个人每个应用的的key不一样:

    public class WeatherActivity extends AppCompatActivity {                                                           
                                                                                                                      
       private ScrollView weatherLayout;                                                                              
                                                                                                                      
       private TextView titleCity;                                                                                    
                                                                                                                      
       private TextView titleUpdateTime;                                                                              
                                                                                                                      
       private TextView degreeText;  //气温                                                                             
                                                                                                                      
       private TextView weatherInfoText;  //天气概况                                                                      
                                                                                                                      
       private LinearLayout forecastLayout;                                                                           
                                                                                                                      
       private TextView aqiText;                                                                                      
                                                                                                                      
       private TextView pm25Text;                                                                                     
                                                                                                                      
       private TextView comfortText;                                                                                  
                                                                                                                      
       private TextView carWashText;                                                                                  
                                                                                                                      
       private TextView sportText;                                                                                    
                                                                                                                      
       @Override                                                                                                      
       protected void onCreate(Bundle savedInstanceState) {                                                           
           super.onCreate(savedInstanceState);                                                                        
           setContentView(R.layout.activity_weather);                                                                 
           initView();                                                                                                
           //定义缓存对象                                                                                                   
           SharedPreferences prefs= PreferenceManager.getDefaultSharedPreferences(this);                              
           String weatherString = prefs.getString("weather",null);                                                    
           if (weatherString!=null){                                                                                  
               //有缓存时直接解析天气数据                                                                                         
               Weather weather = Utility.handleWeatherResponse(weatherString);                                        
               showWeatherInfo(weather);                                                                              
           }                                                                                                          
           else {                                                                                                     
               //无缓存时去服务器查询天气信息                                                                                       
               String weatherId = getIntent().getStringExtra("weather_id");                                           
               weatherLayout.setVisibility(View.INVISIBLE);                                                           
               requestWeather(weatherId);                                                                             
           }                                                                                                          
       }                                                                                                              
        /*根据天气ID请求天气信息*/                                                                                              
       private void requestWeather(final String weatherId) {                                                          
           String weatherUrl = "http://guolin.tech/api/weather?cityid = "+                                            
                   weatherId+"&key = 8614c6b9de8145b3a0ef78a277cc2db4";                                               
           HttpUtil.sendOKHttpRequest(weatherUrl, new Callback() {                                                    
               @Override                                                                                              
               public void onFailure(Call call, IOException e) {                                                      
                   e.printStackTrace();                                                                               
                   runOnUiThread(new Runnable() {                                                                     
                       @Override                                                                                      
                       public void run() {                                                                            
                           Toast.makeText(WeatherActivity.this,"从网上获取天气信息失败",                                         
                                   Toast.LENGTH_SHORT).show();                                                        
                       }                                                                                              
                   });                                                                                                
               }                                                                                                      
               @Override                                                                                              
               public void onResponse(Call call, Response response) throws IOException {                              
                   final String responseText = response.body().string();                                              
                   final Weather weather = Utility.handleWeatherResponse(responseText);                               
                   runOnUiThread(new Runnable() {                                                                     
                       @Override                                                                                      
                       public void run() {                                                                            
                           if (weather!=null&&"ok".equals(weather.status)) {                                          
                               SharedPreferences.Editor editor = PreferenceManager.                                   
                                       getDefaultSharedPreferences(WeatherActivity.this).edit();                      
                               editor.putString("weather",responseText);                                              
                               editor.apply();                                                                        
                               showWeatherInfo(weather);                                                              
                           }                                                                                          
                           else {                                                                                     
                               Toast.makeText(WeatherActivity.this,"获取天气信息失败",                                        
                                       Toast.LENGTH_SHORT).show();                                                    
                           }                                                                                          
                       }                                                                                              
                   });                                                                                                
               }                                                                                                      
           });                                                                                                        
       }                                                                                                              
                                                                                                                      
       //缓存数据下处理并展示Weather实体类中的数据                                                                                     
       private void showWeatherInfo(Weather weather) {                                                                
           String cityName = weather.basic.cityName;                                                                  
           String updateTime = weather.basic.update.updateTime.split(" ")[1]; //split:分解                              
           String degree = weather.now.tempeture+"°C";                                                                
           String weatherInfo = weather.now.more.info;                                                                
           titleCity.setText(cityName);                                                                               
           titleUpdateTime.setText(updateTime);                                                                       
           degreeText.setText(degree);                                                                                
           weatherInfoText.setText(weatherInfo);                                                                      
           forecastLayout.removeAllViews();                                                                           
           for (Forecast forecast : weather.forecastList){                                                            
               View view = LayoutInflater.from(this).inflate(R.layout.forecast_item,forecastLayout,false);            
               TextView dateText = (TextView)view.findViewById(R.id.date_text);                                       
               TextView infoText = (TextView)view.findViewById(R.id.info_text);                                       
               TextView maxText = (TextView)view.findViewById(R.id.max_text);                                         
               TextView minText = (TextView)view.findViewById(R.id.min_text);                                         
               dateText.setText(forecast.date);                                                                       
               infoText.setText(forecast.more.info);                                                                  
               maxText.setText(forecast.temperature.max);                                                             
               minText.setText(forecast.temperature.min);                                                             
               forecastLayout.addView(view);                                                                          
           }                                                                                                          
           if (weather.aqi != null){                                                                                  
                    aqiText.setText(weather.aqi.city.aqi);                                                            
                    pm25Text.setText(weather.aqi.city.pm25);                                                          
           }                                                                                                          
           String comfort = "舒适度:" +weather.suggestion.comfort.info;                                                  
           String carWash = " 洗车指数:" +weather.suggestion.carWash.info;                                                
           String sport = "运动建议:" +weather.suggestion.sport.info;                                                     
           comfortText.setText(comfort);                                                                              
           carWashText.setText(carWash);                                                                              
           sportText.setText(sport);                                                                                  
           weatherLayout.setVisibility(View.VISIBLE);                                                                 
       }                                                                                                              
                                                                                                                      
       //初识化控件                                                                                                        
       private void initView() {                                                                                      
           weatherLayout = (ScrollView) findViewById(R.id.weather_layout);                                            
           titleCity = (TextView)findViewById(R.id.title_city);                                                       
           titleUpdateTime = (TextView)findViewById(R.id.title_update_time);                                          
           degreeText = (TextView)findViewById(R.id.degree_text);                                                     
           weatherInfoText = (TextView)findViewById(R.id.weather_info_text);                                          
           forecastLayout = (LinearLayout)findViewById(R.id.forecast_layout);                                         
           aqiText = (TextView)findViewById(R.id.api_text);                                                           
           pm25Text = (TextView)findViewById(R.id.pm25_text);                                                         
           comfortText = (TextView) findViewById(R.id.comfort_text);                                                  
           carWashText = (TextView) findViewById(R.id.car_wash_text);                                                 
           sportText = (TextView)findViewById(R.id.sport_text);                                                       
       }                                                                                                              
    }   
    

    实现省市县列表界面跳转到天气界面的逻辑:
    ,修改ChooseAreaFragment,如下:

       //列表任意一栏被点击,则...
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Log.d("ChooseAreaFragment","列表被点了的...");
                    if (currentLevel == LEVEL_PROVINCE){   //当前选中的级别为省份时
                        selectedProvince = provinceList.get(position);  //当前点击为选中状态
                        queryCities();//查询市的方法
                    }
                    else if (currentLevel == LEVEL_CITY){
                        selectedCity = cityList.get(position);
                        queryCounties();
                    }
    
                    /*以下实现地区天气界面*/
                    else if (currentLevel == LEVEL_COUNTY){
                        String weatherId = countyList.get(position).getWeatherId();
                        Intent intent = new Intent(getActivity(),WeatherActivity.class);
                        intent.putExtra("weather_id",weatherId);
                        startActivity(intent);
                        getActivity().finish();
                    }
                }
            });
    

    在MainActivity中加入一个缓存数据的判断如下:
    public class MainActivity extends AppCompatActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
            if (prefs.getString("weather",null)!=null){
                Intent intent = new Intent(this,WeatherActivity.class);
                startActivity(intent);
                finish();
            }
        }
    }
    

    运行程序后发现和风天气的API接口以及更新升级了,也就是以上代码运行会存在Bug,如图:

    所以去看一下和风天气的开发文档:
    https://www.heweather.com/documents/sdk/android
    在来开发。

    展开全文
  • 作者:wanbo地址:https://juejin.im/post/5db8cee351882557134d0411新的 Android Studio 4.0 更换了全新...
        

    640?wx_fmt=other

    作者:wanbo

    地址:https://juejin.im/post/5db8cee351882557134d0411


    新的 Android Studio 4.0 更换了全新的启动界面,在今天 Google I/O 中官方发布了 Android Studio 3.5 的 beta 版,一个月之后发布了 Android Studio 3.6 beta 版,而最近的 Android Dev Summit 中为我们带来了 Android Studio 4.0 预览版,今天我们就来看一下,新的 Android Studio 4.0 为开发者带来了哪些新体验!

    接下来我会依据 Android Dev Summit 分享的内容以及自己的理解,为大家介绍 Android Studio 4.0 的最新进展,没关注的小伙伴记得关注订阅鸭!如果觉得这些文章有点意思,记得分享转发评论点赞鸭!

    编译构建方面

    640?wx_fmt=other

    新的 Build 窗口,在每一次 Build 之后,会出现一个新的 Build Speed 窗口,我们可以在这个窗口里面查看在整个 Build 期间不同插件、不同任务的耗时,可以做针对性修复。同时还会提示我们哪些插件是每一次 Build 的时候永远都在执行的,帮助我们发现问题,减少不必要的插件执行,缩短 Build 时间。这里面有很多分类,有兴趣的同学可以逐个去研究。

    640?wx_fmt=other

    在之前的文章中,我向大家分享过一些好的 Kotlin 项目,其中包括一个 Gradle 官方开源的 Koltin-DSL-sample。

    现在 Android Studio 4.0 完善了 Kotlin Gradle DSL 的代码提示、在 IDE 中可以直接查看 DSL 的文档。我们都知道之前默认的 Groovy 写法中,Android Studio 会自动帮助我们检查现有依赖库是否有新版本更新,现在针对 Kotlin Gradle DSL 也保留支持了这一特性。

    640?wx_fmt=other

    在编译方面,增加了新的 coreLibraryDesugaringEnabled true 指令,开启这个指令,我们可以使用 Java 8 中的某些高级 API。

    640?wx_fmt=other

    例如上图所示的,list.stream() 方法,默认情况下,它只能在 API 24 以上使用,通过开启 coreLibraryDesugaringEnabled 能够消除版本的限制,在低于 API 24 的设备上也可以使用此方法。目前此指令支持 java.util.stream、java.time、java.util.function、ConcurrentHashMap 等。此功能的目的在于解决旧版本上由于无法使用 Java 高级 API 而产生的持续性 bug 无法得到修复的问题。

    640?wx_fmt=other

    新的 Android Studio 4.0 在编辑 ProGuard 文件时,提供的语法高亮、代码提示和错误检查,同时和 Refactor Name 的时候,ProGuard 文件中对应的字段也会及时更新。

    640?wx_fmt=other

    新增了 viewBinding 指令,当我们开启设置为 true 的时候,编译器会为我们生成一个视图绑定类,即下图中的 ActivityMainBinding。

    640?wx_fmt=other

    viewBinding 的目的在于确保我们在代码中所使用的 View 是试图中确切存在的。防止使用findViewById 为空引起崩溃。(不过我在 4.0 canary 1 上面没有开启成功,应该是还有 bug 😂)

    视图方面

    目前我们编写 UI 有三种方式,xml、代码编写自定义 View、Jetpack Compose。目前这三种方式全部在 Android Studio 4.0 上支持预览。

    640?wx_fmt=other

    三者的预览界面都是一样的,分三种模式:编辑、预览、编辑+预览。别的不说自定义 View 支持预览那真是太方便了,能极大的提升开发效率。

    640?wx_fmt=other

    而且,xml 的视图预览中支持多种不同分辨率设备的同时预览,还可以预览国际化时不同语言的排版情况,以及色盲模式的支持。(当然后面两项在 4.0 canary 1 中还没出现,只是在官方演示视频中做了讲解)

    640?wx_fmt=other

    还有一项很牛逼的东西,就是 Android Studio 4.0 支持嵌入式模拟器,注意上图中的图像界面,不是我们第一个说的预览界面,是真正的模拟器,左边开发右边调试,再也不用切屏幕了。

    640?wx_fmt=other

    Layout Inspector 也得到了更新,之前的 Layout Inspector 类似于布局快照,切换界面后,需要重新启动 Layout Inspector 。Android Studio 4.0 中  Layout Inspector 支持实时自动更新,当我们的设备切换页面后,布局分析器中的页面也会更新,同时关于资源文件的显示也更加完备,增加了完整调用链的信息展示。还有一个特牛逼的功能(划重点了!)就是 Layout Inspector 支持 3D 模型检查,就像下图这样:

    640?wx_fmt=gif

    虽然官方视频中说到这些都会在 Android Studio 4.0 中出现,不过以我目前能下载到的 canary 1 版本来说,自定义 View 预览、嵌入式模拟器、新的 Layout Inspector 都没有找到,后续的 canary 应该会逐步支持。

    动画方面

    有一期推送中我向大家介绍了:Android 8 种动画你用过几个?,最后一个就是 MotionLayout,但当时我也说了:
    使用 MotionLayout 我们需要在 xml 中自定义 MotionScene,在 MotionScene 中指定不同 Layout 之间的变化。
    查看到官方的 Demo 之后,说实话这种动画编写方式还是有些繁琐的,还好这次 Android Studio 4.0 支持了新的动画编辑器,让我们可以通过可视化的操作,来创建 MotionLayout 动画。

    640?wx_fmt=gif

    我们可以指定 Layout 在 start 和 end 两个状态下的布局,设置动画持续时间,点击上方的 Transition 线,就可以预览动画,是不是非常简单!而且我们可以在持续时间中,任意添加关键帧,设置每一帧的状态,更细小颗粒度的控制动画效果,关键帧可以设置属性、相对位置。有了 MotionLayout 和全新的动画编辑器,在 Android 上做动画限制你的不再是 API 而是你的想象力。

    其他

    640?wx_fmt=other

    全新的 Resource Manager 支持多种资源的查看和管理,例如图片、颜色、布局、字符串、动画等等。

    640?wx_fmt=other

    内置的 Materiel Design Icon 提供了多种样式的选择:填充、线性、双色、圆角、矩形,终于不用自己切图了😂。

    640?wx_fmt=other

    IDE 内置了很多简写代码指令模版,帮助我们快速使用,同时支持自定义插入,看了这次分享,才发现自己对 Android Studio 的使用还停留在会用的阶段,从来没有深入研究过,例如我最近才发现可以使用 File → New → Import Sample 查看官方提供了最佳实践代码,有 AAC 架构、有动画、有 CameraX、有 NDK 各种分类应有尽有,评论告诉我,我应该不说最后一个知道这个功能的吧😂。

    640?wx_fmt=other

    以上就是在本次 Android Dev Summit 中 Android Studio 最新进展的部分内容,当然在这些功能的背后,IDE 本身的内存占用、编译速度、都有很大的提升,不然也不会直接版本号跳跃到 4.0,想想隔壁苹果 Xcode 都出道 11 了,Android Studio 才到 4.0 真是慢工出细活啊。

                            喜欢 就关注吧,欢迎投稿!

    640?wx_fmt=jpeg

    展开全文
  • Android Studio —— DOWNLOAD —— DOWNLOAD ANDROID STUDIO(来进行下载,下载的是最新版本) 勾选同意协议,点击开始下载 三 安装Android Studio 1.双击安装软件,打开后点击Next继续下一步;...

    一 进入官网

    进入Android Studio官网,选择 Android Studio 点击进去;

    二 下载

     Android Studio —— DOWNLOAD —— DOWNLOAD ANDROID STUDIO(来进行下载,下载的是最新版本)

    勾选同意协议,点击开始下载

     

    三 安装Android Studio

    1.双击安装软件,打开后点击 Next 继续下一步;

    2.在安装到第二步的时候,会出现以下界面

        Android Virtual Device,是系统自带模拟器,如果不用系统模拟器就不勾选,自己下载其他模拟器(这里选择的是勾选);

    3.如果需要修改安装目录,可点击 Browse..修改,点击 Next 继续下一步;

    4.等待安装配置完成,点击 Next 继续下一步;

    5.点击 Install 安装;

     

    四 导入设置文件

    如果是第一次安装AS,还需要继续进行下面配置安装

    点击 OK 继续下一步,如果本地有AS的设置文件 setting.jar,勾选第一项选择设置文件导入,如果没有设置文件,勾选第二项不导入设置文件;

     

    找不到SDK错误提示
    在启动的时候会弹出错误弹框提示,点击 Cancel

     

    五 AS的安装向导界面

     

    1.点击 Next 继续下一步;

     

    2.选择安装类型
    可选择 Standard(标准) 或 Custom(自定义) 类型安装(这里选择的是Standard);

    3.选择主题模板

    4.安装SDK
    选择所需要的安装组件,点击 Next 继续下一步。如果没有安装 SDK,会默认安装 SDK 到C盘,下载最新的版本,不可修改。如果已安装 SDK,会自动指定 SDK的本地路径;

     

     

    5.SDK下载配置
    确认安装配置,点击 Finish 继续下一步;

    6  SDK下载完成
    点击 Finish 完成

     

    7  AS欢迎界面

    8  更换,下载SDK

    在欢迎页右下角,选择 "Configure" —> "SDK Manager"

    设置SDK存放目录,以及更换下载Android版本

     

    展开全文
  • 已经有一年的时间没有使用 Android studio 了,最近有个项目需要继续安卓app版本升级,又重新安装了android studio 3.5.1。没想到折腾了一天才搞好。 安装记录如下: 1,下载安装Java SE8u221 安装android studio...

     

    已经有一年的时间没有使用 Android studio 了,最近有个项目需要继续安卓app版本升级,又重新安装了android studio 3.5.1。没想到折腾了一天才搞好。

    安装记录如下:

    1,下载安装Java SE8u221

    安装android studio 前,需要先安装 Java。Oracle 网站上已经有Java SE 13了,开始安装了一下有问题,

    还是选择先安装以前熟悉的Windows 10 64位操作系统下使用的SE 8u221版本Java SE Development Kit 8u221。

    https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

     

    桌面-此电脑-属性-高级系统设置-环境变量-系统变量中,

    1.1 系统变量,新建添加   JAVA_HOME    D:\Java\jdk1.8.0_221
    1.2 系统变量,path 中添加     %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin
    1.3 系统变量 ,新建CLASS_PATH ,添加 %JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;


    2, 下载android studio 3.5.1 正式版

    下载google 网站需要翻墙。国内的下载链接:https://developer.android.google.cn/studio/
        android-studio-ide-191.5900203-windows.exe

    这个网站速度快, android 3.5.1 是2019年的正式版本了。

    桌面-此电脑-属性-高级系统设置-环境变量-系统变量中,

    2.1 系统变量,新建添加    ANDROID_HOME      D:\Android Studio
    2.2 系统变量,在path 中增加   %ANDROID_HOME%;%ANDROID_HOME%\tools;%ANDROID_HOME%\build-tools;%ANDROID_HOME%\platform-tools;

    3, 下载安装 Android SDK 软件开发工具套件

    下载链接:https://www.androiddevtools.cn/

    选择SDK Tools 下的 windows平台的   installer_r24.4.1-windows.exe  ,安装到D:\Android\android-sdk 下

    下面一行的那个压缩的比较大,why?

    4,下载安装 Android Gradle plugin and Google Maven dependencies

    项目Gradle 自动化构建插件和Maven 依赖库

    在 https://developer.android.google.cn/studio/ 页面下方点击最后一行stable 右边的蓝色的Google Marven dependence

    弹出协议页面,接受协议,下载到本地,解压到android studio目录下


    5,配置Android studio

    点击最近添加的 Android studio 图标,选择第一行 start a new Android Studio project

     

    choose a activity

    建议选择最常见的 Bottom Navigation Activity 

    Name:HelloMoon,项目名称由自己设。

    Package name: 程序包名,自动生成的是com.example.HelloMoon, 由自己设,

    Save location:项目文件保存位置,如果没有,可以在D盘创建Project 目录,每个项目再根据项目名称创建一个子目录,如HelloMoon。

    language: 缺省是Kotlin,还可以选Java。 原先Java 开发人员一般使用Eclipse ,现在许多转向 Android studio。

    minimum API level:点下拉按钮选一个,下方会显示支持这个安卓系统版本的用户设备的百分比,一般选达到95%以上的API就可以了,因为百分比是动态的。

    点击页面下方的按钮 finish ,你的第一个项目就创建成功了。由于是第一次,系统需要同步一些软件配置,请耐心等一段时间

    6,配置Android studio

    配置完成后,Android studio才能正常编译和运行

    6.1 配置Android SDK

    点击file->setting->Appearance & Behavior->system Settings->Android SDK,

    页面上方出现Android SDK location,

    如果和你实际安装的Android SDK目录不一致,点击右边的edit ,选择正确的Android SDK安装目录。

    勾选show Package Details,上方出现Android platform的各版本,根据实际需求选择,

    如果不清楚,就 API level大于19的platform 左边都勾选。点击右下角按钮apply,系统就会自动下载,等待完成。

    然后点击页面上方的SDK Tools,勾选右下角的show Package Details,页面中出现的各个工具,建议全勾选。

    点击右下角按钮apply,系统就会自动下载,等待完成。

    可以看前面的 Appearance & Behavior->system Settings->updates配置如下

    6.2 配置项目构建管理文件

    6.2.1,项目的 gradle/build.gradle (Project)

    // Top-level build file where you can add configuration options common to all sub-projects/modules.

    buildscript {

        repositories {

              jcenter()

             google()

            }

      dependencies {

          classpath 'com.android.tools.build:gradle:3.5.1'

          // NOTE: Do not place your application dependencies here; they belong

          // in the individual module build.gradle files

          }

    }

    allprojects {

        repositories {

            jcenter()

           google()

           }

    }

    task clean(type: Delete) {

        delete rootProject.buildDir

    }

    6.2.2,app的 gradle/build.gradle (module:app)

    apply plugin: 'com.android.application'
    
    apply plugin: 'kotlin-android'
    
    apply plugin: 'kotlin-android-extensions'
    
    android {
        compileSdkVersion 29
        buildToolsVersion "29.0.2"
        defaultConfig {
            applicationId "com.example.myapplication"
            minSdkVersion 26
            targetSdkVersion 29
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
        implementation 'androidx.appcompat:appcompat:1.1.0'
        implementation 'androidx.core:core-ktx:1.0.2'
        implementation 'com.google.android.material:material:1.0.0'
        implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
        implementation 'androidx.navigation:navigation-fragment:2.0.0'
        implementation 'androidx.navigation:navigation-ui:2.0.0'
        implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
        implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0'
        implementation 'androidx.navigation:navigation-ui-ktx:2.0.0'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'androidx.test.ext:junit:1.1.0'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    }

    6.2.3, gradle.properities 

    systemProp.https.proxyPort=80
    systemProp.http.proxyHost= maven.aliyun.com
    systemProp.https.proxyHost= maven.aliyun.com
    systemProp.http.proxyPort=80
    

    6.2.4, gradle-wrapper.properities(Gradle Version)

    distributionBase=GRADLE_USER_HOME
    distributionPath=wrapper/dists
    zipStoreBase=GRADLE_USER_HOME
    zipStorePath=wrapper/dists
    distributionUrl=https://services.gradle.org/distributions/gradle-5.4.1-all.zip

    这时候可以点击菜单Build 下的 make project , build bundles/APK,看能否编译项目了。

    其中file -> Project structure 的配置如下:

    6.3 配置Android AVD (android 虚拟设备)

    选择 Tools-AVD Manager,在弹出的页面左下角选择 Create Virtual Device,

    在category-> phone,选择一款手机型号做模拟器,点击按钮next,选择一个模拟器运行的API版本。

    下载完成后,点击按钮 finish,成功后,在AVD 管理页面可以看到添加的虚拟设备。点右上角x,关闭页面即可。

    make project 成功后,可以点击 Run - debug app 或 run app。

    需要 Templates 中的目标类型,点击左上方的 + 号添加,如 Android App

    在右边页面进行配置, 如module :app,底下,点击 + 号添加 发布前的新配置,如Build Project

    点击Apply, 激活配置。

    完成以上步骤后,点击 run- debug,选择app,

    Gradle 忙完后,就会出现一个模拟安卓手机了。

     

    Android studio 开发环境的基本安装和配置完成。

     

    展开全文
  • android studio的安装,史上最详细!!欢迎前来观看,感觉有用就点波关注吧!custom 欢迎前来观看,感觉有用就点波关注吧! 1、首先下载Android studio安装包,可以从 http://www.android-studio.org/ 下载最新...
  • 准备:已装过要卸载,且删除C:\user\yourname\下.android,.AndroidStudio,gradle3个文件夹。 1.1 cmd命令窗口,ping dl.google.com,得到ip203.208.43.101,把dl-ssl….和dl…都指向这个IP,具体:...
  • ...gt;New-&gt;New Project, 其中的open是打开一个Android项目 ...3.选择Android 虚拟机的版本,版本越低运行起来越快,其他的无需勾选。...4.选择Android 的模板,选择基础类android 的空模板Empty ...
  • 实现一个 Android 应用,界面呈现如下效果: 三、 实验过程 (1)标题  首先我们建立一个TextView控件来写标题。 实验对标题的要求如下: 1 标题字体大小 20sp(android:textSize="20sp") ...
  • AS的安装及第一个AS中android项目的搭建 前言:前段时间公司搞了个 "校企合作" 的项目,要求公司人员去学校对学生进行阶段性的专业培训,荣幸的我被派去当了回“老师”;哈哈,真的有点“打肿脸充胖子”的感觉;...
  • Android studio 入门教程

    2020-07-30 23:32:03
    Android studio 入门教程,想学Android studio平台的朋友可以下载看看。。。。
  • 这是AndroidStudio系列教程的第二篇。这次,我使用csdn的markdown来写博客,挺好用的。上一节我们讲到了jdk和as的安装,hello world应用初体验。但漏掉了一些东西,现在补回来。adb工具adb工具来自sdk,adb==android...
  • 好记性不如烂笔头,对as的一些快捷键,小技巧总是记不住。通过写博客,可快速整理知识,帮助记忆。项目结构 ...包名(androidTest)(test)->一些测试代码就写在这里 res -> 资源目录文件夹 drawable
  • 相信大家对Android Studio已经不陌生了,Android Studio是Google于2013 I/O大会针对Android开发推出的新的开发工具,目前很多开源项目都已经在采用,Google的更新速度也很快,明显能感觉到这是Android开发的未来,...
  • 这是一门快速入门Android开发课程,顾名思义是让大家能快速入门Android开发。 学完能让你学会如下知识点: Android的发展历程 搭建Java开发环境 搭建Android开发环境 ...
  • Android基础入门教程——1.2.2 使用Android Studio开发Android APP标签(): Android基础入门教程写在前面 本节将介绍如何使用Android Studio开发Android APP,和前面Eclipse + ADT + SDK搭建Android开发环境一样...
  • Android Studio 教程入门开发第一个程序 2018.09.11 14:3016005浏览 开发第一应用 可以开发属于自己的应用,是否有点小激动?好吧!让我们开始,首先点击Start a new Android Studio Project创建工程: 接...
  • 史上最详细的Android Studio系列教程合集,带书签 一--下载和安装 二--基本设置与运行 三--快捷键 四--Gradle基础 五--Gradle命令详解与导入第三方包
  • AndroidStudio基础教程

    2016-05-26 13:24:32
    AndroidStudio基础教程百度云 1.Android视图结构,适用于大部分的开发工作 2.对AndroidStudio进行相关的设置(Ctrl+Alt+S)  字体 16号建议 4.导入eclipse的adt工程  关闭现有工程(打开AS的欢迎界面)->选择...
  • Android Studio入门到精通(清晰版),一本好的书籍,适合入门学习
1 2 3 4 5 ... 20
收藏数 42,777
精华内容 17,110
关键字:

android studio