手把手教你完成Android期末大作业(多功能应用型APP)

Posted 晚风Serein

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手把手教你完成Android期末大作业(多功能应用型APP)相关的知识,希望对你有一定的参考价值。

前言

Android期末作业,估摸着也花了整整5天。里面可能会缺少某些细节,如果跟着做有不会的评论就行,每天都会看,尽力解答。

功能

  • 待办
  • 专注计时
  • 音乐
  • 天气

实现步骤

一、底部菜单栏切换页

1.添加依赖

dependencies 
    implementation 'com.google.android.material:material:1.2.1'

2.在res资源文件夹下新建一个menu文件夹,创建底部导航的菜单布局文件

  • 创建对应数量的item,为每个菜单栏选项
  • 给每个item定义title(标题),icon(图标)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/menu_task"
        android:icon="@drawable/menu_task"
        android:title="事项"/>

    <item
        android:id="@+id/menu_accounts"
        android:icon="@drawable/menu_task"
        android:title="专注"/>

    <item
        android:id="@+id/menu_absorbed"
        android:icon="@drawable/menu_task"
        android:title="音乐"/>

    <item
        android:id="@+id/menu_weather"
        android:icon="@drawable/menu_task"
        android:title="每日先知"/>
</menu>

3.在activity_main布局页面引入 com.google.android.material.bottomnavigation.BottomNavigationView 控件

控件属性:

  • app:labelVisibilityMode="labeled"取消定义三个以上按钮文字不显示的效果
  • app:itemBackground="@null" 取消水波纹的效果
  • app:itemIconTint设置图标的颜色
  • app:itemTextColor设置字体的颜色
  • app:menu="@menu/bottom_navi_menu"将menu引入
<?xml version="1.0" encoding="utf-8"?>
<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"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".MainActivity">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="60dp"
        />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        app:labelVisibilityMode="labeled"
        app:itemBackground="@null"
        app:menu="@menu/bottom_navi_menu"
        />
</RelativeLayout>

4.依次创建每个页面的Fragment类及布局文件,如Task页面

<!-- task_fragment.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">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Task PAGE"
        android:textSize="40dp"
        android:gravity="center"
        />
</LinearLayout>
// TaskFragment.java
public class TaskFragment extends Fragment 
    //重写onCreateView, fragment绑定布局文件
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
        View view = inflater.inflate(R.layout.task_fragment, container, false);
        return view;
    


5.在MainActivity.java中进行设置BottomNavigation选择监听事件对fragment进行管理。

public List<Fragment> fragmentList = new ArrayList<>();
private FragmentManager fragmentManager;

// 底部导航栏模块
public void InitBottomNavigation() 
    // 添加五个fragment实例到fragmentList,以便管理
    fragmentList.add(new TaskFragment());
    fragmentList.add(new AbsorbedFragment());
    fragmentList.add(new MusicFragment());
    fragmentList.add(new WeatherFragment());

    //建立fragment管理器
    fragmentManager = getSupportFragmentManager();

    //管理器开启事务,将fragment实例加入管理器
    fragmentManager.beginTransaction()
        .add(R.id.FragmentLayout, fragmentList.get(0), "TASK")
        .add(R.id.FragmentLayout, fragmentList.get(1), "ABSOTBED")
        .add(R.id.FragmentLayout, fragmentList.get(2), "MUSIC")
        .add(R.id.FragmentLayout, fragmentList.get(3), "WEATHER")
        .commit();

    //设置fragment显示初始状态
    fragmentManager.beginTransaction()
        .show(fragmentList.get(1))
        .hide(fragmentList.get(0))
        .hide(fragmentList.get(2))
        .hide(fragmentList.get(3))
        .commit();

    //设置底部导航栏点击选择监听事件
    BottomNavigationView bottomNavigationView = findViewById(R.id.BottomNavigation);
    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() 
        @SuppressLint("NonConstantResourceId")
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) 
            // return true : show selected style
            // return false: do not show
            switch (item.getItemId()) 
                case R.id.menu_task:
                    ShowFragment(0);
                    return true;
                case R.id.menu_accounts:
                    ShowFragment(1);
                    return true;
                case R.id.menu_absorbed:
                    ShowFragment(2);
                    return true;
                case R.id.menu_weather:
                    ShowFragment(3);
                    return true;
                default:
                    Log.i(TAG, "onNavigationItemSelected: Error");
                    break;
            
            return false;
        
    );


public void ShowFragment(int index) 
    fragmentManager.beginTransaction()
        .show(fragmentList.get(index))
        .hide(fragmentList.get((index + 1) % 4))
        .hide(fragmentList.get((index + 2) % 4))
        .hide(fragmentList.get((index + 3) % 4))
        .commit();

二、天气显示界面

1、添加依赖(用于获取和解析天气数据)

    implementation 'com.google.code.gson:gson:2.8.6'
    implementation 'com.squareup.okhttp3:okhttp:4.9.0'

2、获取天气API接口,这里以临海市为例。使用OkHttp请求天气数据,使用Log打印测试是否能成功获取

public void RefreshWeatherData() 
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder().url(weatherUrl).build();
            client.newCall(request).enqueue(new Callback() 
                @Override
                public void onFailure(@NonNull Call call, @NonNull IOException e) 
                    e.printStackTrace();
                

                @Override
                public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException 
                    String weatherJson = response.body().string();
                    Weather weather = new Gson().fromJson(weatherJson, Weather.class);
                    Log.i(TAG, "onResponse: "+weatherJson);
                
            );
        

3、Json数据获取成功后,根据Json数据的结构建立Weather类用于解析Json数据。

// class Weather

public class Weather 
    private String city;		//城市名
    private String update_time;	//更新时间
    private List<DayData> data;	//每天的天气数据列表,data.get(0)为当天数据

    /* 
    	getter and setter 
    */


// class DayData
public class DayData 
    private String wea;			//天气状况
    private String tem;			//当前温度
    private String tem1;		//最高温
    private String tem2;		//最低温
    private String humidity; 	//湿度
    private String air_level;	//空气质量等级
    private String air_tips;	//空气质量小提示

    /* 
    	getter and setter 
    */

4、由于OkHttp的请求是在子线程中进行的,需要使用Handler消息队列机制将解析出来的Weather实例发送到主线程用以显示在界面上。

//消息处理类
public class MyHandler extends Handler 
    @Override
    public void handleMessage(@NonNull Message msg) 
        super.handleMessage(msg);
        //what == 1   天气消息
        if (msg.what == 1)
            ShowWeatherInfo((Weather) msg.obj);
    


public void ShowWeatherInfo(Weather weather) 
    String city = weather.getCity();
    String wea = weather.getData().get(0).getWea();
    String maxTem = weather.getData().get(0).getTem1();
    String minTem = weather.getData().get(0).getTem2();
    String tem = weather.getData().get(0).getTem();
    String humidity = "湿度           " + weather.getData().get(0).getHumidity();
    String air_level = "空气指数   " + weather.getData().get(0).getAir_level();

    // tem  tem1  tem2  city  wea  rain  pm  image
    ((TextView) findViewById(R.id.cityView)).setText(city);
    ((TextView) findViewById(R.id.weaView)).setText(wea);
    ((TextView) findViewById(R.id.mmtemView)).setText(
        String.format("%s° / %s°", minTem.substring(0, minTem.length() - 1), maxTem.substring(0, maxTem.length() - 1)));
    ((TextView) findViewById(R.id.temView)).setText(tem.substring(0, tem.length() - 1) + "°");
    ((TextView) findViewById(R.id.humidityView)).setText(humidity);
    ((TextView) findViewById(R.id.levelView)).setText(air_level);
    
    ShowWeatherImage(wea);	//根据天气状况wea显示对应的天气图片,这里不详细说明,使用switch就行
    

5、别忘了在OkHttp请求完成时发送消息

public void RefreshWeatherData() 
    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder().url(weatherUrl).build();
    client.newCall(request).enqueue(new Callback() 
        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) 
            e.printStackTrace();
        

        @Override
        public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException 
            String weatherJson = response.body().string();
            Weather weather = new Gson().fromJson(weatherJson, Weather.class);
            Message message = new Message();
            message.what = 1;
            message.obj = weather;
            myHandler.sendMessage(message);
        
    );

6、优化xml布局

三、待办事项界面

这里由于ListView是放在Fragment中的,所以直接在MainAcitivity.java中设置适配器可能会出现数据没法显示的bug。所以我直接把从数据库获取数据,Adapter的定义,ListView设置适配器的模块搬到了TaskFragment.java中。

1.在task.xml中添加ListView,先不用设置UI样式,先把数据拿到并显示在界面上

<?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">
    <TextView
        android:id="@+id/taskText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="事项"/>
    <ListView
        android:id="@+id/taskListView"
        android:layout_width="match_parent"
        android:layout_height="match_parent以上是关于手把手教你完成Android期末大作业(多功能应用型APP)的主要内容,如果未能解决你的问题,请参考以下文章

手把手教你完成Android期末大作业(多功能应用型APP)

CSDN博客太火了也教你做一个——(期末web大作业)

Android开发 学生求助了期末大作业

合肥工业大学python大作业之爬虫(手把手教你爬取微博热搜)

软件测试02:6大实际案例手把手教你设计测试点

手把手教你Android来去电通话自动录音的方法