当前位置:   article > 正文

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

安卓期末大作业

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;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

}




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



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

public List 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;

    }

});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105

}

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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

}




[]( )二、天气显示界面

-------------------------------------------------------------------



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



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
implementation 'com.google.code.gson:gson:2.8.6'

implementation 'com.squareup.okhttp3:okhttp:4.9.0'
  • 1
  • 2
  • 3



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



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

            }

        });

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31



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



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

// class Weather

public class Weather {

private String city;		//城市名

private String update_time;	//更新时间

private List<DayData> data;	//每天的天气数据列表,data.get(0)为当天数据



/* 

	getter and setter 

*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

}

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

*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

}




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



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

//消息处理类

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

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

}

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就行
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

}




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



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

    }

});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

}




6、优化xml布局



[]( )三、待办事项界面

-------------------------------------------------------------------



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



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



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
<?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"/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23



2.创建task\_item.xml布局文件(这里注意线性布局的方向及宽高,以保证task\_item能放在ListView中)



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
<?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">



<TextView

    android:id="@+id/task_content"

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:textColor="@color/black"

    android:textSize="30dp"

    android:text="TextView" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19



3.新建TaskItem类,存放事项数据



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

package com.example.daily.tasks;

public class TaskItem {

private int id;

private String content;

private String type;

private int status;



public TaskItem(int id, String type, String content, int status){

    this.id = id;

    this.type = type;

    this.content = content;

    this.status = status;

}



// 自行添加Get和Set方法
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

}




4.在TaskFragment.java中创建SQLite数据库并获取待办事项的数据



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

public class TaskFragment extends Fragment {

private static final String TAG = TaskFragment.class.getName();

private List<TaskItem> taskList = new ArrayList<>();



@Nullable

@Override

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.task, container, false);

    

    ReadTaskDataFromSQL();



    //测试数据获取是否正常

    for(TaskItem item : taskList){

        Log.i(TAG, "taskList "+item.getId()+" "+item.getContent());

    }

       

    return view;

}



//读取数据库并将数据存到taskList

public void ReadTaskDataFromSQL(){

    MySQLiteOpenHelper openHelper = new MySQLiteOpenHelper(getActivity());

    SQLiteDatabase readDatabase = openHelper.getReadableDatabase();

    

    Cursor cursor = readDatabase.query(

            "task",

        	new String[]{"id", "type", "content", "status"},

        	null,null,null,null,null

    );

    

    while(cursor.moveToNext()){

        TaskItem task = new TaskItem(

                cursor.getInt(0), 

                cursor.getString(1), 

                cursor.getString(2), 

                cursor.getInt(3)

        );

        taskList.add(task);

    }

    

}



//创建SQLite数据库

public class MySQLiteOpenHelper extends SQLiteOpenHelper{



    public MySQLiteOpenHelper(@Nullable Context context) {

        super(context, "Daily.db", null, 1);

    }



    @Override

    public void onCreate(SQLiteDatabase db) {

        Log.i(TAG, "onCreate: sqlite");

        //创建待办事项数据表

        String create_sql =

                "create table task(" +

                        "id INTEGER PRIMARY KEY AUTOINCREMENT, " +

                        "content varchar(50), " +

                        "type varchar(50), " +

                        "status int);";

        db.execSQL(create_sql);

    }

    

    @Override

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127

}




5.数据获取正常以后,建立ListView适配器。这里涉及到缓存convertView的使用,使用convertView可以防止每创建一个item时就解析一个布局,这样效率肯定不高。convertView是Android提供的用于缓存的View,在第一次渲染item时,将将解析出来的View放入缓存convertView,在下一次渲染item的时候,判断convertView是否为空即可。



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

public class TaskAdapter extends BaseAdapter{

@Override

public int getCount() {

    //测试getCount返回值是否正常

    Log.i(TAG, "getCount: "+taskList.size());

    return taskList.size();

}



@Override

public Object getItem(int position) {

    return taskList.get(position);

}



@Override

public long getItemId(int position) {

    return taskList.get(position).getId();

}



@Override

public View getView(int position, View convertView, ViewGroup parent) {

    //测试getView是否执行

    Log.i(TAG, "getView: "+position);



    ViewHolder viewHolder;

    TaskItem task = (TaskItem) getItem(position);



    if(convertView == null){

        viewHolder = new ViewHolder();

        convertView = LayoutInflater.from(getActivity()).inflate(R.layout.task_item, null);

        viewHolder.taskItemTextView = convertView.findViewById(R.id.task_content);



        convertView.setTag(viewHolder);

    }else{

        viewHolder = (ViewHolder) convertView.getTag();

    }



    viewHolder.taskItemTextView.setText(task.getId()+"  "+task.getContent());



    return convertView;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77

}

public class ViewHolder{

TextView taskItemTextView;
  • 1

}




6.在onCreateView中设置ListView的适配器



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

private List taskList = new ArrayList<>();

private TaskAdapter taskAdapter;

private ListView taskListView;

@Nullable

@Override

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.task, container, false);



taskListView = view.findViewById(R.id.taskListView);



taskAdapter = new TaskAdapter();



taskListView.setAdapter(taskAdapter);



ReadTaskDataFromSQL();

return view;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

}




**7.设计每一条待办事项的布局样式,如图所示,布局设计就不放原码了,使用多个线性布局的嵌套,gravity,margin属性即可实现。**



**img:task-2.jpg**



**8.根据待办事项的状态显示不同按钮,并标记待办事项的重要程度。**



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

public void ShowTaskContent(View convertView, TaskItem task){

	//显示事项内容

    TextView content = ((ViewHolder) convertView.getTag()).taskContent;

    int status = task.getStatus();



    content.setText(task.getContent());



    //事项已完成 中划线 灰色

    if(status == 1){

        content.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);

        content.setTextColor(getResources().getColor(R.color.GRAY, null));

    }

    //事项未完成 无中划线 黑色

    if(status == 0){

        content.getPaint().setFlags(0);

        content.setTextColor(getResources().getColor(R.color.black, null));

    }

    //事项失败 无中划线 灰色

    if(status == -1){

        content.getPaint().setFlags(0);

        content.setTextColor(getResources().getColor(R.color.GRAY, null));

    }



}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

public void ShowTaskLevel(View convertView, int level){

    // 显示事项重要级别 level :  0~3 四个优先级 Ⅰ Ⅱ Ⅲ Ⅳ

    TextView levelText = ((ViewHolder) convertView.getTag()).taskLevel;



    if(level == 0){

        levelText.setText("Ⅰ");

        levelText.setTextColor(getResources().getColor(R.color.level_0, null));

    }

    if(level == 1){

        levelText.setText("Ⅱ");

        levelText.setTextColor(getResources().getColor(R.color.level_1, null));

    }

    if(level == 2){

        levelText.setText("Ⅲ");

        levelText.setTextColor(getResources().getColor(R.color.level_2, null));

    }

    if(level == 3){

        levelText.setText("Ⅳ");

        levelText.setTextColor(getResources().getColor(R.color.level_3, null));

    }



}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41



**9.在顶部添加五个TextView作为分类查看事项菜单,点击某一分类即可查看该分类下的所有事项,并修改被点击TextView 的样式。**



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

/** 菜单栏模块 **/

public void SetTypeMenuOnClick(View view){

typeMenuList.add((TextView) view.findViewById(R.id.TypeMenu_default));

typeMenuList.add((TextView) view.findViewById(R.id.TypeMenu_work));

typeMenuList.add((TextView) view.findViewById(R.id.TypeMenu_study));

typeMenuList.add((TextView) view.findViewById(R.id.TypeMenu_life));



int[] color = {

    getResources().getColor(R.color.defaultColor, null),

    getResources().getColor(R.color.workColor, null),

    getResources().getColor(R.color.studyColor, null),

    getResources().getColor(R.color.lifeColor, null),

};



for(int i=0; i<4 ;i++){

    int finalI = i; //分类索引值

    typeMenuList.get(i).setOnClickListener(v -> {

        // 点击分类的一项后设置样式

        typeMenuList.get(finalI).setTextColor(Color.BLACK);

        typeMenuList.get(finalI).setBackgroundColor(Color.WHITE);



        typeMenuList.get((finalI+1) % 4).setBackgroundColor(color[(finalI+1) % 4]);

        typeMenuList.get((finalI+1) % 4).setTextColor(Color.WHITE);



        typeMenuList.get((finalI+2) % 4).setBackgroundColor(color[(finalI+2) % 4]);

        typeMenuList.get((finalI+2) % 4).setTextColor(Color.WHITE);



        typeMenuList.get((finalI+3) % 4).setBackgroundColor(color[(finalI+3) % 4]);

        typeMenuList.get((finalI+3) % 4).setTextColor(Color.WHITE);



        // 显示某一类待办数据,这里筛选taskList即可

        List<TaskItem> typeTaskList = new ArrayList<>();

        String[] types = {"全部", "工作","学习","生活"};

        /*  分类索引值

            0 全部

            1 工作

            2 学习

            3 生活

             */

        // 点击工作 学习 生活时分类

        // TypeNow 是一个全局变量,表示当前的分类

        TypeNow = types[finalI];

        Log.i(TAG, "SetTypeMenuOnClick: "+TypeNow);

        ReadTaskFromDatabase();



    });



}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91

}




**10.task.xml布局右上角加入一个switch控件用以隐藏已完成事项。**



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

//隐藏已完成Switch

    Switch hideCompletedTaskSwitch = view.findViewById(R.id.HideCompletedTaskView);

    hideCompletedTaskSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

        @Override

        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

            if(isChecked)   isHideCompleted = true;

            else            isHideCompleted = false;

            

            // isHideCompleted 是一个全局变量,表示当前是否隐藏已完成事项

            ReadTaskFromDatabase();

        }

    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21



完成9,10步之后就需要修改读取数据库的模块,加入TypeNow和isHideCompleted变量加以控制。



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

public void ReadTaskFromDatabase(){

if (taskList.size()!=0) {

    taskList.clear();

}



Cursor cursor = readDatabase.query(

    "task",

    new String[]{"id", "type", "level","content", "info", "status"},

    null,

    null,

    null,

    null,

    null

);



//隐藏,有分类

if(isHideCompleted && !TypeNow.equals("全部")){

    //只获取未完成事项

    while(cursor.moveToNext()){

        if((cursor.getInt(5) == 0 ) && (cursor.getString(1).equals(TypeNow))){

            TaskItem task = new TaskItem(

                cursor.getInt(0),

                cursor.getString(1),

                cursor.getInt(2),

                cursor.getString(3),

                cursor.getString(4),

                cursor.getInt(5)

            );

            taskList.add(task);

        }



    }



}

//不隐藏,有分类

if(!isHideCompleted && !TypeNow.equals("全部")){

    while(cursor.moveToNext()){

        if(cursor.getString(1).equals(TypeNow)){

            TaskItem task = new TaskItem(

                cursor.getInt(0),

                cursor.getString(1),

                cursor.getInt(2),

                cursor.getString(3),

                cursor.getString(4),

                cursor.getInt(5)

            );

            taskList.add(task);

        }

    }

}

//隐藏,不分类

if(isHideCompleted && TypeNow.equals("全部")){

    while(cursor.moveToNext()){

        if(cursor.getInt(5) == 0){

            TaskItem task = new TaskItem(

                cursor.getInt(0),

                cursor.getString(1),

                cursor.getInt(2),

                cursor.getString(3),

                cursor.getString(4),

                cursor.getInt(5)

            );

            taskList.add(task);

        }



    }

}

else{

    while(cursor.moveToNext()){

        TaskItem task = new TaskItem(

            cursor.getInt(0),

            cursor.getString(1),

            cursor.getInt(2),

            cursor.getString(3),

            cursor.getString(4),

            cursor.getInt(5)

        );

        taskList.add(task);

    }

}



// 别忘了通知ListView适配器数据变化

taskAdapter.notifyDataSetChanged();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163

}




11、添加事项,这里使用的是在整个RelativeLayout布局中添加一个ImageView作为添加事项的按钮,并定义点击事件,点击时弹出对话框,在对话框中输入添加事项的信息。



自定义对话框需要先设计一个layout布局文件add\_task\_dialog.xml



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
<?xml version="1.0" encoding="utf-8"?>

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

android:layout_width="match_parent"

android:orientation="vertical"

android:paddingLeft="15dp"

android:paddingRight="15dp"

android:paddingBottom="20dp"

android:paddingTop="10dp"

android:layout_height="wrap_content">



<TextView

    android:text="添加事项"

    android:textColor="@color/black"

    android:textSize="25dp"

    android:layout_width="match_parent"

    android:gravity="center"

    android:layout_height="50dp"/>



<LinearLayout

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:paddingLeft="15dp"

    android:paddingRight="15dp"

    android:orientation="horizontal">



    <TextView

        android:id="@+id/textView"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:textSize="20dp"

        android:textColor="@color/black"

        android:layout_marginRight="15dp"

        android:text="事项" />



    <EditText

        android:id="@+id/addTaskContentEdit"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_weight="1"

        android:ems="10"

        android:inputType="textPersonName"

        android:text="" />

</LinearLayout>



<RelativeLayout

    android:layout_width="match_parent"

    android:layout_marginTop="10dp"

    android:paddingLeft="15dp"

    android:paddingRight="15dp"

    android:layout_height="wrap_content">



    <LinearLayout

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:orientation="vertical">



        <TextView

            android:id="@+id/textView2"

            android:layout_width="160dp"

            android:layout_height="wrap_content"

            android:textSize="20dp"

            android:textColor="@color/black"

            android:text="事项分类" />



        <RadioGroup

            android:id="@+id/typeRadioGroup"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content">



            <RadioButton

                android:id="@+id/radioButton8"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/workColor"

                android:text="工作" />



            <RadioButton

                android:id="@+id/radioButton7"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/studyColor"

                android:text="学习" />



            <RadioButton

                android:id="@+id/radioButton6"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/lifeColor"

                android:text="生活" />



            <RadioButton

                android:id="@+id/radioButton5"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/defaultColor"

                android:text="不分类" />

        </RadioGroup>

    </LinearLayout>



    <LinearLayout

        android:layout_width="160dp"

        android:layout_height="wrap_content"

        android:layout_alignParentEnd="true"

        android:orientation="vertical">



        <TextView

            android:id="@+id/textView3"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:textSize="20dp"

            android:textColor="@color/black"

            android:text="重要级别" />



        <RadioGroup

            android:id="@+id/levelRadioGroup"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content">



            <RadioButton

                android:id="@+id/radioButton"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/level_0"

                android:text="0 重要且紧急" />



            <RadioButton

                android:id="@+id/radioButton2"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/level_1"

                android:text="1 重要但不紧急" />



            <RadioButton

                android:id="@+id/radioButton3"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/level_2"

                android:text="2 不重要但紧急" />



            <RadioButton

                android:id="@+id/radioButton4"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/level_3"

                android:text="3 不重要且不紧急" />

        </RadioGroup>

    </LinearLayout>



</RelativeLayout>



<LinearLayout

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:layout_marginTop="10dp"

    android:paddingLeft="15dp"

    android:paddingRight="15dp"

    android:orientation="horizontal">



    <TextView

        android:id="@+id/textView4"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:textSize="20dp"

        android:textColor="@color/black"

        android:layout_marginRight="15dp"

        android:text="备注" />



    <EditText

        android:id="@+id/addTaskInfoEdit"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:ems="10"

        android:inputType="textPersonName"

        android:text="" />

</LinearLayout>



<LinearLayout

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:gravity="center"

    android:layout_marginTop="10dp"

    android:orientation="horizontal">



    <Button

        android:id="@+id/cancelAddButton"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_marginRight="100dp"

        android:text="取消" />



    <Button

        android:id="@+id/confirmAddButton"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"



        android:text="确定" />

</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389



12、定义一个方法,实现弹出添加事项界面的对话框,并设置确认和取消按钮的点击事件,确认按钮即添加该事项到数据库并显示



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

public void ShowAddTaskDialog(){

//获取添加事项布局实例

View addView = getLayoutInflater().inflate(R.layout.add_task_dialog, null);



// 将该布局添加到对话框

final AlertDialog addDialog = new 																AlertDialog.Builder(getActivity()).setView(addView).create();

addDialog.show();



//获取对话框中的布局控件

Button cancelButton = (Button) addView.findViewById(R.id.cancelAddButton);

Button confirmButton = (Button) addView.findViewById(R.id.confirmAddButton);

EditText contentEdit = (EditText) addView.findViewById(R.id.addTaskContentEdit);

EditText infoEdit = (EditText) addView.findViewById(R.id.addTaskInfoEdit);

RadioGroup typeGroup = (RadioGroup) addView.findViewById(R.id.typeRadioGroup);

RadioGroup levelGroup = (RadioGroup) addView.findViewById(R.id.levelRadioGroup);



typeGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

    @Override

    public void onCheckedChanged(RadioGroup group, int checkedId) {

    }

});

levelGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

    @Override

    public void onCheckedChanged(RadioGroup group, int checkedId) {

    }

});



//确定按钮

confirmButton.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

        // 获取输入的事项内容和备注

        String addContent = contentEdit.getText().toString();

        String addInfo = infoEdit.getText().toString();



        //RadioGroup的选择项

        RadioButton typeSelectBtn = (RadioButton)               									addView.findViewById(typeGroup.getCheckedRadioButtonId());

        String addType = typeSelectBtn.getText().toString();

        RadioButton levelSelectBtn = (RadioButton) 													addView.findViewById(levelGroup.getCheckedRadioButtonId());

        int addLevel = 																				Integer.parseInt(levelSelectBtn.getText().toString().substring(0,1));



        //插入数据库

        InsertTaskToDatabase(

            new TaskItem(addType, addLevel, addContent, addInfo, 0)

        );

        addDialog.dismiss();

    }

});



// 取消按钮

cancelButton.setOnClickListener(new View.OnClickListener() {

    @Override

    public void onClick(View v) {

        addDialog.dismiss();

    }

});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109

}




13、然后在添加事项的点击事件中调用ShowAddTaskDialog()即可



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

//添加事项的按钮

ImageView addTaskImage = (ImageView) view.findViewById(R.id.addTaskImage);

addTaskImage.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

    ShowAddTaskDialog();

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

});




14.长按某条事项弹出对话框,显示事项信息,可以修改,删除,标记失败。和添加事项的对话框实现原理相同,这里不详细说明,给出代码供参考



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
<?xml version="1.0" encoding="utf-8"?>

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

android:layout_width="match_parent"

android:orientation="vertical"

android:paddingLeft="15dp"

android:paddingRight="15dp"

android:paddingBottom="20dp"

android:paddingTop="10dp"

android:layout_height="wrap_content">



<TextView

    android:text="事项信息"

    android:textColor="@color/black"

    android:textSize="25dp"

    android:layout_width="match_parent"

    android:gravity="center"

    android:layout_height="50dp"/>



<LinearLayout

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:paddingLeft="15dp"

    android:paddingRight="15dp"

    android:orientation="horizontal">



    <TextView

        android:id="@+id/textView"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:textSize="20dp"

        android:textColor="@color/black"

        android:layout_marginRight="15dp"

        android:text="事项" />



    <EditText

        android:id="@+id/addTaskContentEdit"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_weight="1"

        android:ems="10"

        android:inputType="textPersonName"

        android:text="" />

</LinearLayout>



<RelativeLayout

    android:layout_width="match_parent"

    android:layout_marginTop="10dp"

    android:paddingLeft="15dp"

    android:paddingRight="15dp"

    android:layout_height="wrap_content">



    <LinearLayout

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:orientation="vertical">



        <TextView

            android:id="@+id/textView2"

            android:layout_width="160dp"

            android:layout_height="wrap_content"

            android:textSize="20dp"

            android:textColor="@color/black"

            android:text="事项分类" />



        <RadioGroup

            android:id="@+id/typeRadioGroup"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content">



            <RadioButton

                android:id="@+id/workButton"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/workColor"

                android:text="工作" />



            <RadioButton

                android:id="@+id/studyButton"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/studyColor"

                android:text="学习" />



            <RadioButton

                android:id="@+id/lifeButton"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/lifeColor"

                android:text="生活" />



            <RadioButton

                android:id="@+id/defaultButton"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/defaultColor"

                android:text="全部" />

        </RadioGroup>

    </LinearLayout>



    <LinearLayout

        android:layout_width="160dp"

        android:layout_height="wrap_content"

        android:layout_alignParentEnd="true"

        android:orientation="vertical">



        <TextView

            android:id="@+id/textView3"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:textSize="20dp"

            android:textColor="@color/black"

            android:text="重要级别" />



        <RadioGroup

            android:id="@+id/levelRadioGroup"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content">



            <RadioButton

                android:id="@+id/level0Button"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/level_0"

                android:text="0 重要且紧急" />



            <RadioButton

                android:id="@+id/level1Button"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/level_1"

                android:text="1 重要但不紧急" />



            <RadioButton

                android:id="@+id/level2Button"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/level_2"

                android:text="2 不重要但紧急" />



            <RadioButton

                android:id="@+id/level3Button"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:textColor="@color/level_3"

                android:text="3 不重要且不紧急" />

        </RadioGroup>

    </LinearLayout>



</RelativeLayout>



<LinearLayout

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:layout_marginTop="10dp"

    android:paddingLeft="15dp"

    android:paddingRight="15dp"

    android:orientation="horizontal">



    <TextView

        android:id="@+id/textView4"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:textSize="20dp"

        android:textColor="@color/black"

        android:layout_marginRight="15dp"

        android:text="备注" />



    <EditText

        android:id="@+id/addTaskInfoEdit"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:ems="10"

        android:inputType="textPersonName"

        android:text="" />

</LinearLayout>



<LinearLayout

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:gravity="center"

    android:layout_marginTop="20dp"

    android:orientation="horizontal">



    <LinearLayout

        android:layout_width="wrap_content"

        android:layout_marginRight="60dp"

        android:orientation="vertical"

        android:layout_height="wrap_content">

        <ImageView

            android:id="@+id/deleteTaskButton"

            android:layout_width="wrap_content"

            android:layout_height="40dp"

            android:adjustViewBounds="true"

            android:src="@drawable/delete_icon"

             />

        <TextView

            android:layout_width="40dp"

            android:layout_height="wrap_content"

            android:textColor="@color/black"

            android:gravity="center"

            android:textSize="15dp"

            android:layout_marginTop="5dp"

            android:text="删除"/>

    </LinearLayout>

    <LinearLayout

        android:layout_width="wrap_content"

        android:orientation="vertical"

        android:layout_height="wrap_content">

        <ImageView

            android:id="@+id/failTaskButton"

            android:layout_width="40dp"

            android:layout_height="40dp"

            android:adjustViewBounds="true"

            android:src="@drawable/fail_icon"

             />

        <TextView

            android:layout_width="40dp"

            android:layout_height="wrap_content"

            android:textColor="#d81e06"

            android:gravity="center"

            android:textSize="15dp"

            android:layout_marginTop="5dp"



            android:text="失败"/>

    </LinearLayout>



    <LinearLayout

        android:layout_width="wrap_content"

        android:layout_marginLeft="60dp"

        android:orientation="vertical"

        android:layout_height="wrap_content">

        <ImageView

            android:id="@+id/modifyTaskButton"

            android:layout_width="40dp"

            android:layout_height="40dp"

            android:adjustViewBounds="true"

            android:src="@drawable/modify_icon"

            android:text="修改" />

        <TextView

            android:layout_width="40dp"

            android:layout_height="wrap_content"

            android:textColor="@color/purple_500"

            android:gravity="center"

            android:textSize="15dp"

            android:layout_marginTop="5dp"

            android:text="修改"/>

    </LinearLayout>

</LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491

  • 1

public void ShowTaskInfoDialog(TaskItem task){

    // 获取传入的事项数据

    String content = task.getContent();

    String type = task.getType();

    int level = task.getLevel();

    String info = task.getInfo();



    //获取布局

    View infoView = getLayoutInflater().inflate(R.layout.task_info_dialog, null);



    final AlertDialog infoDialog = new AlertDialog.Builder(getActivity()).setView(infoView).create();

    infoDialog.show();



    //获取对话框中的布局控件

    EditText contentEdit = (EditText) infoView.findViewById(R.id.addTaskContentEdit);

    EditText infoEdit = (EditText) infoView.findViewById(R.id.addTaskInfoEdit);

    RadioGroup typeGroup = (RadioGroup) infoView.findViewById(R.id.typeRadioGroup);

    RadioGroup levelGroup = (RadioGroup) infoView.findViewById(R.id.levelRadioGroup);

    ImageView deleteImage = (ImageView) infoView.findViewById(R.id.deleteTaskButton);

    ImageView modifyImage = (ImageView) infoView.findViewById(R.id.modifyTaskButton);

    ImageView failImage = (ImageView) infoView.findViewById(R.id.failTaskButton);



    //显示task事项信息

    contentEdit.setText(content);

    infoEdit.setText(info);

    SetTypeRadioGroupSelected(typeGroup, type);

    SetLevelRadioGroupSelected(levelGroup, level);



    //删除按钮

    deleteImage.setOnClickListener(new View.OnClickListener() {

        @Override

        public void onClick(View v) {

            DeleteTaskToDatabase(task);

            infoDialog.dismiss();

        }

    });



    //失败按钮

    failImage.setOnClickListener(new View.OnClickListener() {

        @Override

        public void onClick(View v) {

            task.setStatus(-1);

            UpDateTaskToDatabase(task);

            //别忘记关闭对话框

            infoDialog.dismiss();

        }

    });



    //修改按钮

    modifyImage.setOnClickListener(new View.OnClickListener() {

        @Override

        public void onClick(View v) {

            // 获取输入的事项内容和备注

            String modifyContent = contentEdit.getText().toString();

            String modifyInfo = infoEdit.getText().toString();



            //RadioGroup的选择项

            RadioButton typeSelectBtn = (RadioButton) infoView.findViewById(typeGroup.getCheckedRadioButtonId());

            String modifyType = typeSelectBtn.getText().toString();

            RadioButton levelSelectBtn = (RadioButton) infoView.findViewById(levelGroup.getCheckedRadioButtonId());

            int modifyLevel = Integer.parseInt(levelSelectBtn.getText().toString().substring(0,1));



            task.setContent(modifyContent);

            task.setInfo(modifyInfo);

            task.setType(modifyType);

            task.setLevel(modifyLevel);



            UpDateTaskToDatabase(task);

            //别忘记关闭对话框

            infoDialog.dismiss();

        }

    });



}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145

  • 1

//在适配器的getView中,设置每条事项的长按事件:调用ShowTaskInfoDialog弹出对话框显示事项的内容

convertView.setOnLongClickListener(new View.OnLongClickListener() {

@Override

public boolean onLongClick(View v) {

    ShowTaskInfoDialog(task);

    return false;

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

});




[]( )四、专注计时界面

-------------------------------------------------------------------



计时的原理是使用Android四大组件之一的Service开启计时线程,并每隔一秒钟发送一次本地广播通知主界面更新布局。



1、创建服务类TimeService,继承自Service。这里在Service类里面定义了一个TimeThread自定义线程类,用以方便线程的挂起和恢复。



  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

public class TimeService extends Service {

private static final String TAG = TimeService.class.getName();



//计时秒数

private int second = 0;



public int getSecond() {

    return second;

}



public void setSecond(int second) {

    this.second = second;

}



@Nullable

@Override

public IBinder onBind(Intent intent) {

    return new LocalBinder();

}



@Override

public void onCreate() {

    Log.i(TAG, "TimeService onCreate: ");

    super.onCreate();

}



@Override

public int onStartCommand(Intent intent, int flags, int startId) {

    Log.i(TAG, "TimeService onStartCommand: ");

    //创建计时线程实例

    timeThread = new TimeThread();

    timeThread.start();

    isRunning = true;

    return super.onStartCommand(intent, flags, startId);

}



@Override

public void onDestroy() {

    Log.i(TAG, "TimeService onDestroy: ");

    super.onDestroy();

}



@Override

public boolean onUnbind(Intent intent) {

    Log.i(TAG, "TimeService onUnbind: ");

    return super.onUnbind(intent);

}



//用于返回本地服务

public class LocalBinder extends Binder{

    public TimeService getService(){

        return TimeService.this;

    }

}



public class TimeThread extends Thread{

    private final Object lock = new Object();

    private boolean pause = false;



    /**

     * 调用该方法实现线程的暂停

     */

    void pauseThread(){

        Log.i(TAG, "pauseTimeThread: ");

        pause = true;

    }

    /*

    调用该方法实现恢复线程的运行

     */

    void resumeThread(){

        Log.i(TAG, "resumeTimeThread: ");

        pause = false;

        synchronized (lock){

            lock.notify();

        }

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

ivate static final String TAG = TimeService.class.getName();

//计时秒数

private int second = 0;



public int getSecond() {

    return second;

}



public void setSecond(int second) {

    this.second = second;

}



@Nullable

@Override

public IBinder onBind(Intent intent) {

    return new LocalBinder();

}



@Override

public void onCreate() {

    Log.i(TAG, "TimeService onCreate: ");

    super.onCreate();

}



@Override

public int onStartCommand(Intent intent, int flags, int startId) {

    Log.i(TAG, "TimeService onStartCommand: ");

    //创建计时线程实例

    timeThread = new TimeThread();

    timeThread.start();

    isRunning = true;

    return super.onStartCommand(intent, flags, startId);

}



@Override

public void onDestroy() {

    Log.i(TAG, "TimeService onDestroy: ");

    super.onDestroy();

}



@Override

public boolean onUnbind(Intent intent) {

    Log.i(TAG, "TimeService onUnbind: ");

    return super.onUnbind(intent);

}



//用于返回本地服务

public class LocalBinder extends Binder{

    public TimeService getService(){

        return TimeService.this;

    }

}



public class TimeThread extends Thread{

    private final Object lock = new Object();

    private boolean pause = false;



    /**

     * 调用该方法实现线程的暂停

     */

    void pauseThread(){

        Log.i(TAG, "pauseTimeThread: ");

        pause = true;

    }

    /*

    调用该方法实现恢复线程的运行

     */

    void resumeThread(){

        Log.i(TAG, "resumeTimeThread: ");

        pause = false;

        synchronized (lock){

            lock.notify();

        }

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-d5MeySBJ-1713223162635)]

[外链图片转存中…(img-qQjAcgZJ-1713223162635)]

[外链图片转存中…(img-8ODmxQ8s-1713223162636)]

[外链图片转存中…(img-cw9SP7gM-1713223162636)]

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

img
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/865925
推荐阅读
相关标签
  

闽ICP备14008679号