Java移动开发案例

wen java案例 2

本文目录导读:

Java移动开发案例

  1. 项目结构
  2. 实体类(Task.java)
  3. 数据库助手(DatabaseHelper.java)
  4. 适配器(TaskAdapter.java)
  5. 主活动(MainActivity.java)
  6. 布局文件
  7. build.gradle 依赖
  8. 功能特点
  9. 运行效果

我来为您提供一个完整的Java移动开发案例 —— 一个简易的待办事项应用(Todo App)

项目结构

TodoApp/
├── app/
│   ├── src/
│   │   ├── main/
│   │   │   ├── java/com/example/todoapp/
│   │   │   │   ├── MainActivity.java
│   │   │   │   ├── TaskAdapter.java
│   │   │   │   ├── Task.java
│   │   │   │   └── DatabaseHelper.java
│   │   │   └── res/
│   │   │       ├── layout/
│   │   │       │   ├── activity_main.xml
│   │   │       │   └── item_task.xml
│   │   │       └── values/
│   └── build.gradle

实体类(Task.java)

package com.example.todoapp;
public class Task {
    private int id;
    private String title;
    private String description;
    private boolean completed;
    private String createDate;
    public Task() {
    }
    public Task(String title, String description, boolean completed, String createDate) {
        this.title = title;
        this.description = description;
        this.completed = completed;
        this.createDate = createDate;
    }
    // Getters and Setters
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public boolean isCompleted() {
        return completed;
    }
    public void setCompleted(boolean completed) {
        this.completed = completed;
    }
    public String getCreateDate() {
        return createDate;
    }
    public void setCreateDate(String createDate) {
        this.createDate = createDate;
    }
}

数据库助手(DatabaseHelper.java)

package com.example.todoapp;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
import java.util.List;
public class DatabaseHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "todo.db";
    private static final int DATABASE_VERSION = 1;
    private static final String TABLE_TASKS = "tasks";
    private static final String COLUMN_ID = "id";
    private static final String COLUMN_TITLE = "title";
    private static final String COLUMN_DESCRIPTION = "description";
    private static final String COLUMN_COMPLETED = "completed";
    private static final String COLUMN_CREATE_DATE = "create_date";
    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        String createTable = "CREATE TABLE " + TABLE_TASKS + " (" +
                COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COLUMN_TITLE + " TEXT NOT NULL, " +
                COLUMN_DESCRIPTION + " TEXT, " +
                COLUMN_COMPLETED + " INTEGER DEFAULT 0, " +
                COLUMN_CREATE_DATE + " TEXT)";
        db.execSQL(createTable);
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_TASKS);
        onCreate(db);
    }
    // 添加任务
    public long addTask(Task task) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(COLUMN_TITLE, task.getTitle());
        values.put(COLUMN_DESCRIPTION, task.getDescription());
        values.put(COLUMN_COMPLETED, task.isCompleted() ? 1 : 0);
        values.put(COLUMN_CREATE_DATE, task.getCreateDate());
        long id = db.insert(TABLE_TASKS, null, values);
        db.close();
        return id;
    }
    // 获取所有任务
    public List<Task> getAllTasks() {
        List<Task> taskList = new ArrayList<>();
        String selectQuery = "SELECT * FROM " + TABLE_TASKS + " ORDER BY " + COLUMN_CREATE_DATE + " DESC";
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);
        if (cursor.moveToFirst()) {
            do {
                Task task = new Task();
                task.setId(cursor.getInt(cursor.getColumnIndex(COLUMN_ID)));
                task.setTitle(cursor.getString(cursor.getColumnIndex(COLUMN_TITLE)));
                task.setDescription(cursor.getString(cursor.getColumnIndex(COLUMN_DESCRIPTION)));
                task.setCompleted(cursor.getInt(cursor.getColumnIndex(COLUMN_COMPLETED)) == 1);
                task.setCreateDate(cursor.getString(cursor.getColumnIndex(COLUMN_CREATE_DATE)));
                taskList.add(task);
            } while (cursor.moveToNext());
        }
        cursor.close();
        db.close();
        return taskList;
    }
    // 更新任务
    public int updateTask(Task task) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(COLUMN_TITLE, task.getTitle());
        values.put(COLUMN_DESCRIPTION, task.getDescription());
        values.put(COLUMN_COMPLETED, task.isCompleted() ? 1 : 0);
        return db.update(TABLE_TASKS, values, COLUMN_ID + " = ?",
                new String[]{String.valueOf(task.getId())});
    }
    // 删除任务
    public void deleteTask(int id) {
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_TASKS, COLUMN_ID + " = ?",
                new String[]{String.valueOf(id)});
        db.close();
    }
}

适配器(TaskAdapter.java)

package com.example.todoapp;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.TaskViewHolder> {
    private List<Task> taskList;
    private Context context;
    private OnTaskListener onTaskListener;
    public interface OnTaskListener {
        void onTaskClick(Task task);
        void onTaskLongClick(Task task);
        void onTaskCheckChange(Task task, boolean isChecked);
    }
    public TaskAdapter(List<Task> taskList, OnTaskListener listener) {
        this.taskList = taskList;
        this.onTaskListener = listener;
    }
    @NonNull
    @Override
    public TaskViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();
        View view = LayoutInflater.from(context)
                .inflate(R.layout.item_task, parent, false);
        return new TaskViewHolder(view);
    }
    @Override
    public void onBindViewHolder(@NonNull TaskViewHolder holder, int position) {
        Task task = taskList.get(position);
        holder.bind(task);
    }
    @Override
    public int getItemCount() {
        return taskList.size();
    }
    class TaskViewHolder extends RecyclerView.ViewHolder {
        TextView titleText;
        TextView descText;
        TextView dateText;
        CheckBox completedCheckBox;
        TaskViewHolder(View itemView) {
            super(itemView);
            titleText = itemView.findViewById(R.id.textTitle);
            descText = itemView.findViewById(R.id.textDescription);
            dateText = itemView.findViewById(R.id.textDate);
            completedCheckBox = itemView.findViewById(R.id.checkCompleted);
            itemView.setOnClickListener(v -> {
                int position = getAdapterPosition();
                if (position != RecyclerView.NO_POSITION && onTaskListener != null) {
                    onTaskListener.onTaskClick(taskList.get(position));
                }
            });
            itemView.setOnLongClickListener(v -> {
                int position = getAdapterPosition();
                if (position != RecyclerView.NO_POSITION && onTaskListener != null) {
                    onTaskListener.onTaskLongClick(taskList.get(position));
                    return true;
                }
                return false;
            });
            completedCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
                int position = getAdapterPosition();
                if (position != RecyclerView.NO_POSITION && onTaskListener != null) {
                    Task task = taskList.get(position);
                    task.setCompleted(isChecked);
                    onTaskListener.onTaskCheckChange(task, isChecked);
                }
            });
        }
        void bind(Task task) {
            titleText.setText(task.getTitle());
            descText.setText(task.getDescription());
            completedCheckBox.setChecked(task.isCompleted());
            // 格式化日期显示
            try {
                SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
                SimpleDateFormat outputFormat = new SimpleDateFormat("MM月dd日 HH:mm", Locale.getDefault());
                Date date = inputFormat.parse(task.getCreateDate());
                if (date != null) {
                    dateText.setText(outputFormat.format(date));
                }
            } catch (Exception e) {
                dateText.setText(task.getCreateDate());
            }
            // 根据完成状态设置样式
            if (task.isCompleted()) {
                titleText.setAlpha(0.5f);
                descText.setAlpha(0.5f);
            } else {
                titleText.setAlpha(1f);
                descText.setAlpha(1f);
            }
        }
    }
}

主活动(MainActivity.java)

package com.example.todoapp;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class MainActivity extends AppCompatActivity implements TaskAdapter.OnTaskListener {
    private RecyclerView recyclerView;
    private TaskAdapter adapter;
    private List<Task> taskList;
    private DatabaseHelper databaseHelper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        databaseHelper = new DatabaseHelper(this);
        taskList = new ArrayList<>();
        initViews();
        loadTasks();
        setupRecyclerView();
    }
    private void initViews() {
        recyclerView = findViewById(R.id.recyclerView);
        FloatingActionButton fab = findViewById(R.id.fabAdd);
        fab.setOnClickListener(v -> showAddTaskDialog());
    }
    private void setupRecyclerView() {
        adapter = new TaskAdapter(taskList, this);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(adapter);
    }
    private void loadTasks() {
        taskList.clear();
        taskList.addAll(databaseHelper.getAllTasks());
        if (adapter != null) {
            adapter.notifyDataSetChanged();
        }
    }
    private void showAddTaskDialog() {
        LayoutInflater inflater = LayoutInflater.from(this);
        View dialogView = inflater.inflate(R.layout.dialog_add_task, null);
        EditText etTitle = dialogView.findViewById(R.id.etTitle);
        EditText etDescription = dialogView.findViewById(R.id.etDescription);
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("添加新任务")
                .setView(dialogView)
                .setPositiveButton("添加", (dialog, which) -> {
                    String title = etTitle.getText().toString().trim();
                    String description = etDescription.getText().toString().trim();
                    if (title.isEmpty()) {
                        Toast.makeText(this, "请输入任务标题", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
                    String createDate = sdf.format(new Date());
                    Task task = new Task(title, description, false, createDate);
                    long id = databaseHelper.addTask(task);
                    if (id > 0) {
                        loadTasks();
                        Toast.makeText(this, "任务添加成功", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(this, "添加失败", Toast.LENGTH_SHORT).show();
                    }
                })
                .setNegativeButton("取消", null)
                .show();
    }
    private void showEditTaskDialog(Task task) {
        LayoutInflater inflater = LayoutInflater.from(this);
        View dialogView = inflater.inflate(R.layout.dialog_add_task, null);
        EditText etTitle = dialogView.findViewById(R.id.etTitle);
        EditText etDescription = dialogView.findViewById(R.id.etDescription);
        etTitle.setText(task.getTitle());
        etDescription.setText(task.getDescription());
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("编辑任务")
                .setView(dialogView)
                .setPositiveButton("保存", (dialog, which) -> {
                    String title = etTitle.getText().toString().trim();
                    String description = etDescription.getText().toString().trim();
                    if (title.isEmpty()) {
                        Toast.makeText(this, "请输入任务标题", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    task.setTitle(title);
                    task.setDescription(description);
                    int result = databaseHelper.updateTask(task);
                    if (result > 0) {
                        loadTasks();
                        Toast.makeText(this, "任务更新成功", Toast.LENGTH_SHORT).show();
                    }
                })
                .setNegativeButton("取消", null)
                .show();
    }
    private void showDeleteDialog(Task task) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("删除任务")
                .setMessage("确定要删除这个任务吗?")
                .setPositiveButton("删除", (dialog, which) -> {
                    databaseHelper.deleteTask(task.getId());
                    loadTasks();
                    Toast.makeText(this, "任务已删除", Toast.LENGTH_SHORT).show();
                })
                .setNegativeButton("取消", null)
                .show();
    }
    @Override
    public void onTaskClick(Task task) {
        showEditTaskDialog(task);
    }
    @Override
    public void onTaskLongClick(Task task) {
        showDeleteDialog(task);
    }
    @Override
    public void onTaskCheckChange(Task task, boolean isChecked) {
        task.setCompleted(isChecked);
        databaseHelper.updateTask(task);
        loadTasks();
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_clear_completed) {
            clearCompletedTasks();
            return true;
        } else if (id == R.id.action_delete_all) {
            deleteAllTasks();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    private void clearCompletedTasks() {
        for (Task task : new ArrayList<>(taskList)) {
            if (task.isCompleted()) {
                databaseHelper.deleteTask(task.getId());
            }
        }
        loadTasks();
        Toast.makeText(this, "已完成的任务已清理", Toast.LENGTH_SHORT).show();
    }
    private void deleteAllTasks() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("清空任务")
                .setMessage("确定要删除所有任务吗?此操作不可恢复!")
                .setPositiveButton("确定", (dialog, which) -> {
                    for (Task task : new ArrayList<>(taskList)) {
                        databaseHelper.deleteTask(task.getId());
                    }
                    loadTasks();
                    Toast.makeText(this, "所有任务已删除", Toast.LENGTH_SHORT).show();
                })
                .setNegativeButton("取消", null)
                .show();
    }
}

布局文件

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp"
        android:clipToPadding="false" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fabAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="添加任务"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        app:srcCompat="@android:drawable/ic_input_add" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

item_task.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    app:cardElevation="4dp"
    app:cardCornerRadius="8dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="16dp">
        <CheckBox
            android:id="@+id/checkCompleted"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical" />
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical"
            android:layout_marginStart="12dp">
            <TextView
                android:id="@+id/textTitle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="18sp"
                android:textStyle="bold"
                android:textColor="@android:color/black" />
            <TextView
                android:id="@+id/textDescription"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="14sp"
                android:textColor="@android:color/darker_gray"
                android:maxLines="3"
                android:ellipsize="end"
                android:layout_marginTop="4dp" />
            <TextView
                android:id="@+id/textDate"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="12sp"
                android:textColor="@color/teal_700"
                android:layout_marginTop="8dp" />
        </LinearLayout>
    </LinearLayout>
</androidx.cardview.widget.CardView>

dialog_add_task.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:padding="16dp">
    <EditText
        android:id="@+id/etTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="任务标题"
        android:inputType="text"
        android:maxLines="1"
        android:textSize="16sp" />
    <EditText
        android:id="@+id/etDescription"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="任务描述(可选)"
        android:inputType="textMultiLine"
        android:minLines="3"
        android:textSize="14sp"
        android:layout_marginTop="12dp" />
</LinearLayout>

menu_main.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/action_clear_completed"
        android:title="清理已完成"/>
    <item
        android:id="@+id/action_delete_all"
        android:title="删除全部"/>
</menu>

build.gradle 依赖

dependencies {
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.9.0'
    implementation 'androidx.recyclerview:recyclerview:1.3.0'
    implementation 'androidx.cardview:cardview:1.0.0'
}

功能特点

  1. 添加任务:通过浮动按钮添加新任务
  2. 编辑任务:点击任务卡片进行编辑
  3. 删除任务:长按任务卡片删除
  4. 标记完成:通过复选框标记任务完成状态
  5. 数据持久化:使用SQLite存储数据
  6. 批量操作:清理已完成、删除全部任务

运行效果

  • 主界面显示任务列表
  • 每个任务包含标题、描述、创建日期和完成状态
  • 支持下拉刷新(可扩展)
  • 支持搜索功能(可扩展)

这个案例涵盖了Android开发的核心知识点:Activity生命周期、RecyclerView适配器、SQLite数据库操作、Material Design组件使用、对话框交互等,是一个完整的学习项目。

抱歉,评论功能暂时关闭!