基于 Android studio 实现停车场管理系统--原创

news2024/11/24 18:40:58

目录

一、项目演示

二、开发环境

三、项目页面

四、项目详情

五、项目完整源码


一、项目演示

二、开发环境

三、项目详情

1.启动页

这段代码是一个简单的Android应用程序启动活动(Activity),具体功能如下:

1. **延迟进入登录页面:**
   - 在 `onCreate()` 方法中,使用 `Handler` 和 `Runnable` 实现了一个延迟执行的功能,延迟时间为3秒。
   - `runnable` 对象的 `run()` 方法调用了 `tomainActive()` 方法,在延迟结束后启动 `LoginRegisterActivity` 并关闭当前的 `StartActivity`。

2. **计时器功能:**
   - 定义了一个内部类 `TimeCount`,继承自 `CountDownTimer`,用于执行一个四秒的倒计时操作,每隔一秒触发一次。
   - `onFinish()` 方法中,倒计时结束后移除了 `handler` 中的 `runnable` 对象,确保不会在倒计时结束后再次跳转到登录页面。

3. **Activity 生命周期方法:**
   - `onCreate()` 方法中,设置了布局文件 `activity_start.xml` 作为界面显示内容,并启动了延迟执行和计时器。
   - `onDestroy()` 方法中未显示重写,但在 `toMainActive()` 方法中的 `finish()` 方法确保了在跳转完成后关闭当前 Activity。

总体来说,该代码实现了在应用启动后延迟3秒进入登录页面,并在倒计时4秒后取消延迟,确保用户在启动页面停留不超过指定时间后自动跳转到登录页面。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#5492ea"
    tools:context=".Activity.StartActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="32dp"
        android:layout_marginTop="32dp"
        android:layout_marginEnd="32dp"
        android:layout_marginBottom="32dp"
        android:background="#5492ea"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/logo" />
</androidx.constraintlayout.widget.ConstraintLayout>

2.登录注册

这段代码实现了一个包含登录和注册功能的活动(Activity),具体功能如下:

1. **界面初始化和控件绑定:**
   - 在 `onCreate()` 方法中,通过 `setContentView()` 方法设置了布局文件 `activity_login_register.xml` 作为界面显示内容,并调用了 `initView()` 方法初始化了界面上的控件。
   - `initView()` 方法中绑定了登录按钮(`llLogin`、`tvLogin`、`viewLogin`)、注册按钮(`llRegister`、`tvRegister`、`viewRegister`)以及用于显示 Fragment 的 `FrameLayout` (`fr`)。

2. **页面切换逻辑:**
   - `Navigation()` 方法设置了登录 (`llLogin`) 和注册 (`llRegister`) 按钮的点击事件监听器。
   - 点击登录按钮时,调用 `setFragment(0)` 方法,切换到登录页面(`LoginFragment`),并设置相关的文本颜色和视图状态。
   - 点击注册按钮时,调用 `setFragment(1)` 方法,切换到注册页面(`RegisterFragment`),同样设置相关的文本颜色和视图状态。

3. **Fragment 切换方法:**
   - `setFragment(int id)` 方法根据传入的 `id` 参数,使用 `FragmentManager` 将对应的 `Fragment` 替换到 `FrameLayout` (`fr`) 中。
   - 当 `id` 为 `0` 时,创建并显示 `LoginFragment`;当 `id` 为 `1` 时,创建并显示 `RegisterFragment`。

4. **颜色和视图控制:**
   - 在点击事件中,通过 `setTextColor()` 方法设置文本颜色,通过 `setVisibility()` 方法控制视图的显示和隐藏,以反映当前选择的是登录还是注册页面。

总体来说,该代码实现了一个简单的登录注册页面切换功能,使用了 `Fragment` 来分别展示登录和注册界面,并通过点击事件处理程序来实现页面切换和视图控制。

package com.example.parking.Activity;

import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;

import com.example.parking.Fragment.LoginFragment;
import com.example.parking.Fragment.RegisterFragment;
import com.example.parking.R;

public class LoginRegisterActivity extends AppCompatActivity {

    private LinearLayout llLogin;
    private TextView tvLogin;
    private View viewLogin;
    private LinearLayout llRegister;
    private TextView tvRegister;
    private View viewRegister;
    private FrameLayout fr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login_register);
        initView();
        Navigation();
        llLogin.callOnClick();
    }

    // 点击控件进行页面转换
    private void Navigation() {
        // 设置llLogin点击事件监听器
        llLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 调用setFragment方法切换到指定页面
                setFragment(0);
                // 设置文本颜色和视图显示状态
                tvLogin.setTextColor(Color.parseColor("#5492ea"));
                viewLogin.setVisibility(View.VISIBLE);
                tvRegister.setTextColor(Color.parseColor("#000000"));
                viewRegister.setVisibility(View.GONE);
            }
        });

        // 设置llRegister点击事件监听器
        llRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 调用setFragment方法切换到指定页面
                setFragment(1);
                // 设置文本颜色和视图显示状态
                tvLogin.setTextColor(Color.parseColor("#000000"));
                viewLogin.setVisibility(View.GONE);
                tvRegister.setTextColor(Color.parseColor("#5492ea"));
                viewRegister.setVisibility(View.VISIBLE);
            }
        });
    }

    // 切换fg页面
    private void setFragment(int id) {
        Fragment fragment = null;
        switch (id) {
            case 0:
                // 创建LoginFragment实例
                fragment = new LoginFragment();
                break;
            case 1:
                // 创建RegisterFragment实例
                fragment = new RegisterFragment();
                break;
        }
        // 使用FragmentManager替换指定布局中的Fragment
        getSupportFragmentManager().beginTransaction().replace(R.id.fr, fragment).commit();
    }

    private void initView() {
        llLogin = findViewById(R.id.ll_login);
        tvLogin = findViewById(R.id.tv_login);
        viewLogin = findViewById(R.id.view_login);
        llRegister = findViewById(R.id.ll_register);
        tvRegister = findViewById(R.id.tv_register);
        viewRegister = findViewById(R.id.view_register);
        fr = findViewById(R.id.fr);
    }
}

3.用户首页

这段代码实现了一个名为 `HomeFragment` 的片段(Fragment),用于显示用户的汽车信息和通知内容。让我们来逐步分析其功能和结构:

1. **布局初始化和视图绑定:**
   - 在 `onCreateView()` 方法中,使用 `LayoutInflater` 加载了 `fragment_home.xml` 布局文件,并通过 `initView(v)` 方法初始化了界面上的控件。
   - `initView(View v)` 方法中,绑定了通知内容的 `TextView` (`tvInform`) 和两个水平方向的 `RecyclerView` (`rvA` 和 `rvB`)。

2. **显示方法 (`show()` 方法):**
   - **通知信息显示:**
     - 通过 `InformHelper` 实例 (`informHelper`) 获取 ID 为 1 的通知信息 (`informById`),如果获取到则将其内容显示在 `tvInform` 中。
   - **汽车信息显示:**
     - **RecyclerViewA:** 显示前五辆汽车的信息。
       - 设置了水平方向的 `LinearLayoutManager`。
       - 从 `carHelper` 获取所有汽车信息列表 (`carList`),并取前五个数据显示。
       - 创建 `CarAdapter` 实例 (`adapterA`),将其设置给 `rvA`。
     - **RecyclerViewB:** 显示剩余汽车信息。
       - 同样设置了水平方向的 `LinearLayoutManager`。
       - 如果汽车总数超过五辆,则显示剩余的汽车数据。
       - 创建 `CarAdapter` 实例 (`adapterB`),将其设置给 `rvB`。

3. **初始化方法 (`initView(View v)` 方法):**
   - 在 `initView(View v)` 方法中,通过 `v.findViewById()` 方法绑定了布局中的各个控件,包括 `tvInform`、`rvA` 和 `rvB`。
   - 初始化了 `carHelper` 和 `informHelper` 实例,用于获取汽车信息和通知信息。

4. **SharedPreferences 使用:**
   - 使用了 `SharedPreferences` 获取存储在 "User" 中的手机号 (`phone`),用于后续可能的用户数据查询或其他操作。

总体来说,`HomeFragment` 主要实现了在用户主页显示通知信息和汽车信息的功能。它通过 `InformHelper` 和 `CarHelper` 来获取和展示数据,并通过两个 `RecyclerView` 分别显示前五个和剩余的汽车信息。

package com.example.parking.Fragment;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.parking.Adapter.CarAdapter;
import com.example.parking.Bean.CarBean;
import com.example.parking.Bean.InformBean;
import com.example.parking.Helper.CarHelper;
import com.example.parking.Helper.InformHelper;
import com.example.parking.R;

import java.util.List;

public class HomeFragment extends Fragment {

    private TextView tvInform;

    private CarHelper carHelper;
    private String phone;
    private RecyclerView rvA, rvB;
    private InformHelper informHelper;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_home, container, false);
        initView(v);
        show();
        return v;
    }

    private void show() {
        // 通过ID获取通知信息
        InformBean informById = informHelper.getInformById(1);
        if (informById != null) {
            // 如果获取到通知信息,设置到TextView中显示
            tvInform.setText(informById.getContent());
        }

        // 设置RecyclerViewA的布局管理器为水平方向的LinearLayoutManager
        LinearLayoutManager layoutManagerA = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
        rvA.setLayoutManager(layoutManagerA);

        // 设置RecyclerViewB的布局管理器为水平方向的LinearLayoutManager
        LinearLayoutManager layoutManagerB = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
        rvB.setLayoutManager(layoutManagerB);

        // 获取所有汽车信息列表
        List<CarBean> carList = carHelper.getAllCars();
        int totalCarCount = carList.size();

        // 获取前五个汽车数据
        List<CarBean> firstFiveCars = carList.subList(0, Math.min(totalCarCount, 5));

        // 获取剩余的汽车数据
        int remainingCarCount = Math.max(totalCarCount - 5, 0);
        List<CarBean> remainingCars = carList.subList(5, totalCarCount);

        // 初始化适配器A,并设置给RecyclerViewA
        CarAdapter adapterA = new CarAdapter(getContext(), firstFiveCars);
        rvA.setAdapter(adapterA);

        // 初始化适配器B,并设置给RecyclerViewB
        CarAdapter adapterB = new CarAdapter(getContext(), remainingCars);
        rvB.setAdapter(adapterB);
    }

    private void initView(View v) {
        tvInform = v.findViewById(R.id.tv_inform);
        carHelper = new CarHelper(getActivity());
        SharedPreferences sharedPreferences = getActivity().getSharedPreferences("User", Context.MODE_PRIVATE);
        phone = sharedPreferences.getString("phone", "");
        rvA = v.findViewById(R.id.rv_a);
        rvB = v.findViewById(R.id.rv_b);
        informHelper = new InformHelper(getActivity());
    }
}

4.用户我的

这段代码实现了一个名为 `MineFragment` 的片段(Fragment),用于展示用户的个人信息,包括用户名、电话号码、头像,并提供了跳转到信息管理、修改密码、车辆管理以及退出登录功能。让我们来逐步分析其功能和结构:

1. **布局初始化和视图绑定:**
   - 在 `onCreateView()` 方法中,使用 `LayoutInflater` 加载了 `fragment_mine.xml` 布局文件,并通过 `initView(v)` 方法初始化了界面上的控件。
   - `initView(View v)` 方法中,绑定了用户头像 (`imgAvatar`)、用户名 (`tvUsername`)、电话号码 (`tvPhone`),以及四个功能按钮 (`llInformation`、`llPassword`、`llCar`、`llQuit`)。

2. **数据显示方法 (`show()` 方法):**
   - **获取用户信息:**
     - 使用 `userHelper` 实例通过存储在 `SharedPreferences` 中的手机号 (`phone`),从数据库中获取用户信息 (`UserBean`)。
     - 如果成功获取到用户信息 (`userByPhone`),则将用户的用户名、电话号码显示在界面上。
   - **显示用户头像:**
     - 如果用户有头像数据 (`avatar` 不为 null),则使用 Glide 库加载并显示头像。
     - 使用了 `Base64.decode()` 解码用户头像数据,并使用 `CircleCrop` 实现圆形裁剪效果,加载到 `imgAvatar` 中。
     - 如果用户没有头像数据,则显示默认的头像图片 (`avatar` 为空时显示 `R.drawable.avatar` 图片)。

3. **功能跳转 (`skip()` 方法):**
   - **信息管理 (`llInformation`)、修改密码 (`llPassword`)、车辆管理 (`llCar`):**
     - 设置了点击事件监听器,点击时分别跳转到 `InformationActivity`、`ModifyPassWordActivity` 和 `CarManagementActivity`。
   - **退出登录 (`llQuit`):**
     - 设置了点击事件监听器,点击时弹出确认退出登录的对话框 (`AlertDialog`)。
     - 如果点击确认,则跳转到 `LoginRegisterActivity` 并结束当前活动 (`getActivity().finish()`),实现退出登录操作。
     - 如果点击取消,则对话框消失,不执行任何操作。

4. **生命周期方法:**
   - 使用了 `onResume()` 方法,在片段恢复时重新调用 `show()` 方法,以确保界面上的数据能够及时更新显示。

5. **使用到的技术和库:**
   - 使用了 `SharedPreferences` 存储用户手机号,用于从数据库中获取用户信息。
   - 使用了 Glide 库加载和显示用户头像,并应用了圆形裁剪的效果。
   - 使用了 `AlertDialog.Builder` 创建对话框,实现用户退出登录的确认操作。

总体来说,`MineFragment` 实现了一个完整的个人信息展示和操作界面,包括用户信息的显示、头像的加载、功能按钮的点击跳转以及退出登录的确认对话框功能。

package com.example.parking.Fragment;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Base64;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
import com.bumptech.glide.request.RequestOptions;
import com.example.parking.Activity.CarManagementActivity;
import com.example.parking.Activity.InformationActivity;
import com.example.parking.Activity.LoginRegisterActivity;
import com.example.parking.Activity.ModifyPassWordActivity;
import com.example.parking.Bean.UserBean;
import com.example.parking.Helper.UserHelper;
import com.example.parking.R;

public class MineFragment extends Fragment {

    private ImageView imgAvatar;
    private TextView tvUsername;
    private TextView tvPhone;
    private LinearLayout llInformation;
    private LinearLayout llPassword;
    private LinearLayout llCar;
    private LinearLayout llQuit;
    private String phone;
    private UserHelper userHelper;

    @Override
    public void onResume() {
        super.onResume();
        show();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_mine, container, false);
        initView(v);
        show();
        skip();
        return v;
    }

    private void skip() {
        // 设置 llInformation 的点击事件监听器
        llInformation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 点击时跳转至 InformationActivity
                Intent intent = new Intent(getActivity(), InformationActivity.class);
                startActivity(intent);
            }
        });

        // 设置 llPassword 的点击事件监听器
        llPassword.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 点击时跳转至 ModifyPassWordActivity
                Intent intent = new Intent(getActivity(), ModifyPassWordActivity.class);
                startActivity(intent);
            }
        });

        // 设置 llCar 的点击事件监听器
        llCar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 点击时跳转至 CarManagementActivity
                Intent intent = new Intent(getActivity(), CarManagementActivity.class);
                startActivity(intent);
            }
        });

        // 设置 llQuit 的点击事件监听器
        llQuit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 弹出确认退出登录的对话框
                AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
                builder.setMessage("确定要退出登录吗?");
                // 点击确定时执行退出登录操作
                builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(getActivity(), LoginRegisterActivity.class);
                        startActivity(intent);
                        getActivity().finish();
                    }
                });
                // 点击取消则不执行任何操作
                builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // 点击取消
                    }
                });

                // 创建并显示对话框
                AlertDialog dialog = builder.create();
                dialog.show();
            }
        });
    }

    private void show() {
        // 通过手机号从数据库获取用户信息
        UserBean userByPhone = userHelper.getUserByPhone(phone);
        // 如果用户信息不为空,则展示用户信息
        if (userByPhone != null) {
            // 设置电话号码文本
            tvPhone.setText("电话:" + userByPhone.getPhone());
            String username = userByPhone.getUsername();
            // 设置用户名文本
            tvUsername.setText(username);

            // 如果用户有头像,则加载并显示头像
            if (userByPhone.getAvatar() != null) {
                // 使用 Glide 加载头像并显示
                Glide.with(getActivity())
                        .load(Base64.decode(userByPhone.getAvatar(), Base64.DEFAULT))
                        .apply(RequestOptions.bitmapTransform(new CircleCrop()))
                        .into(imgAvatar);
            } else {
                // 如果用户没有头像,则显示默认头像
                imgAvatar.setImageResource(R.drawable.avatar);
            }
        }
    }

    private void initView(View v) {
        imgAvatar = v.findViewById(R.id.img_avatar);
        tvUsername = v.findViewById(R.id.tv_username);
        tvPhone = v.findViewById(R.id.tv_phone);
        llInformation = v.findViewById(R.id.ll_information);
        llPassword = v.findViewById(R.id.ll_password);
        llCar = v.findViewById(R.id.ll_car);
        llQuit = v.findViewById(R.id.ll_quit);
        SharedPreferences sharedPreferences = getActivity().getSharedPreferences("User", Context.MODE_PRIVATE);
        phone = sharedPreferences.getString("phone", "");
        userHelper = new UserHelper(getActivity());
    }
}

5.用户个人信息

这段代码实现了一个名为 `InformationActivity` 的活动(Activity),用于展示和编辑用户的个人信息,包括用户名、手机号、头像、性别、生日和地址等。让我们来逐步分析其功能和结构:

1. **布局初始化和视图绑定:**
   - 在 `onCreate()` 方法中,使用 `setContentView()` 方法加载了 `activity_information.xml` 布局文件,并通过 `initView()` 方法初始化了界面上的控件。
   - `initView()` 方法中,绑定了返回按钮 (`imgBack`)、头像 (`imgAvatar`)、用户名 (`tvUsername`)、手机号 (`tvPhone`)、性别 (`tvSex`)、生日 (`tvBirthday`)、地址 (`tvAddress`) 的控件,以及保存按钮 (`btnSave`) 和各个信息项的布局 (`llAvatar`、`llUsername` 等)。

2. **显示用户信息 (`show()` 方法):**
   - **从数据库获取用户信息:**
     - 使用 `userHelper` 实例根据存储在 `SharedPreferences` 中的手机号 (`phone`),从数据库中获取用户信息 (`UserBean`)。
     - 如果成功获取到用户信息 (`user`),则从用户对象中获取各个信息字段,并将它们显示在对应的 `TextView` 和 `ImageView` 中。
     - 如果用户的头像字段 (`avatar`) 为 null,则显示默认的头像图片 (`R.drawable.avatar`)。
     - 如果用户的性别、生日或地址字段为 null,则显示默认的提示文本 ("请输入性别"、"请输入生日"、"请输入地址")。

3. **编辑用户信息 (`dialog(TextView textView)` 方法):**
   - **创建编辑对话框:**
     - 使用 `AlertDialog.Builder` 创建对话框,加载自定义布局 `dialog_information.xml`。
     - 对于每个信息项的布局 (`llUsername`、`llSex`、`llBirthday`、`llAddress`),设置点击事件监听器。
     - 点击事件触发时,弹出对话框编辑对应的信息。用户可以输入新的信息,并在确定按钮点击后将新信息设置到对应的 `TextView` 中。

4. **保存用户信息 (`save()` 方法):**
   - **保存按钮点击事件:**
     - 设置保存按钮 (`btnSave`) 的点击事件监听器。
     - 获取头像 (`imgAvatar`) 的图片并将其转换为 Base64 编码格式。
     - 获取用户输入的用户名、性别、生日和地址信息,并调用 `userHelper` 的方法更新用户信息(除了手机号外的信息)。
     - 根据更新结果显示相应的提示信息,成功则显示 "保存成功!",失败则显示 "保存失败!"。

5. **处理相册选择和图片裁剪 (`onActivityResult()` 方法):**
   - **相册选择和图片裁剪结果处理:**
     - 当用户点击头像布局 (`llAvatar`) 时,打开系统相册 (`Intent.ACTION_PICK`)。
     - 在相册选择图片后,调用 `UCrop` 库进行图片裁剪,并设置裁剪的宽高比为 1:1。
     - 在裁剪完成后 (`REQUEST_CROP_PICTURE` 请求码),加载裁剪后的图片并显示为圆形,使用 Glide 加载图片并显示到 `imgAvatar` 控件上。

6. **返回按钮点击事件 (`back()` 方法):**
   - 返回按钮 (`imgBack`) 的点击事件监听器,点击时结束当前活动 (`finish()`),返回上一个界面。

7. **使用到的技术和库:**
   - 使用了 `SharedPreferences` 存储用户手机号,用于从数据库中获取用户信息。
   - 使用 Glide 库加载和显示用户头像,并应用了圆形裁剪的效果。
   - 使用了 `UCrop` 库进行图片裁剪,实现用户头像的选择和编辑功能。
   - 使用了 `AlertDialog.Builder` 创建对话框,实现用户信息的编辑和保存功能。

总体来说,`InformationActivity` 实现了一个完整的用户个人信息展示和编辑界面,用户可以查看和修改自己的个人信息,并可以选择头像进行编辑。

package com.example.parking.Activity;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.Base64;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
import com.bumptech.glide.request.RequestOptions;
import com.example.parking.Bean.UserBean;
import com.example.parking.Helper.UserHelper;
import com.example.parking.R;
import com.yalantis.ucrop.UCrop;

import java.io.ByteArrayOutputStream;
import java.io.File;

public class InformationActivity extends AppCompatActivity {
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_information);
        back();
        show();
    }
 

    // 设置各个信息项的点击事件监听器
    private void llClick() {
        llAvatar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 打开相册
                Intent intent = new Intent(Intent.ACTION_PICK);
                // 设置类型为图片
                intent.setType("image/*");
                startActivityForResult(intent, REQUEST_SELECT_PICTURE);
            }
        });

        llUsername.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 弹出对话框编辑用户名
                dialog(tvUsername);
            }
        });
        llPhone.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 提示手机号不支持修改
                Toast.makeText(InformationActivity.this, "手机号不支持修改!", Toast.LENGTH_SHORT).show();
            }
        });

        llSex.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 弹出对话框编辑性别
                dialog(tvSex);
            }
        });
        llBirthday.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 弹出对话框编辑生日
                dialog(tvBirthday);
            }
        });
        llAddress.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 弹出对话框编辑地址
                dialog(tvAddress);
            }
        });
    }

    // 创建编辑对话框的方法
    private void dialog(final TextView textView) {
        // 创建AlertDialog构建器
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        // 获取自定义布局文件dialog_car.xml的视图
        View dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_information, null);

        // 设置对话框的视图
        builder.setView(dialogView);

        // 获取对话框中的控件
        final EditText etInformation = dialogView.findViewById(R.id.et_information);
        Button btnOk = dialogView.findViewById(R.id.btn_ok);

        // 创建AlertDialog对象
        final AlertDialog dialog = builder.create();
        // 设置确定按钮的点击事件
        btnOk.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 获取输入的信息
                String information = etInformation.getText().toString();
                if (information.isEmpty()) {
                    // 提示输入信息不能为空
                    Toast.makeText(InformationActivity.this, "请输入信息!", Toast.LENGTH_SHORT).show();
                    return;
                }
                // 将信息设置到传入的textView上
                textView.setText(information);
                // 关闭对话框
                dialog.dismiss();
            }
        });
        // 显示对话框
        dialog.show();
    }


    // 处理从相册选择图片后的返回结果
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_SELECT_PICTURE && resultCode == RESULT_OK) {
            if (data != null) {
                Uri selectedImageUri = data.getData();
                // 调用UCrop进行图片裁剪
                UCrop.of(selectedImageUri, Uri.fromFile(new File(getCacheDir(), "cropped_image")))
                        .withAspectRatio(1, 1)
                        .start(this, REQUEST_CROP_PICTURE);
            }
        } else if (requestCode == REQUEST_CROP_PICTURE && resultCode == RESULT_OK) {
            if (data != null) {
                Uri croppedImageUri = UCrop.getOutput(data);
                // 使用Glide加载裁剪后的图片并显示为圆形
                Glide.with(this)
                        .load(croppedImageUri)
                        .skipMemoryCache(true)  // 跳过内存缓存
                        .diskCacheStrategy(DiskCacheStrategy.NONE)  // 不使用磁盘缓存
                        .circleCrop()
                        .into(imgAvatar);
            }
        }
    }


    // 显示用户信息的方法
    private void show() {
        // 根据手机号获取用户信息
        UserBean user = userHelper.getUserByPhone(phone);
        if (user != null) {
            // 获取用户信息的各个字段
            String avatar = user.getAvatar();
            String username = user.getUsername();
            String phone = user.getPhone();
            String sex = user.getSex();
            String birthday = user.getBirthday();
            String address = user.getAddress();
            password = user.getPassword();
            // 如果用户头像为空,设置默认头像
            if (avatar == null) {
                imgAvatar.setImageResource(R.drawable.avatar);
            } else {
                // 加载用户头像
                Glide.with(this)
                        .load(Base64.decode(avatar, Base64.DEFAULT))
                        .apply(RequestOptions.bitmapTransform(new CircleCrop()))
                        .into(imgAvatar);
            }
            // 设置用户名、手机号、性别、生日和地址信息到对应的TextView上
            tvUsername.setText(username);
            tvPhone.setText(phone);
            if (sex != null) {
                tvSex.setText(sex);
            } else {
                tvSex.setText("请输入性别");
            }
            if (birthday != null) {
                tvBirthday.setText(birthday);
            } else {
                tvBirthday.setText("请输入生日");
            }
            if (address != null) {
                tvAddress.setText(address);
            } else {
                tvAddress.setText("请输入地址");
            }

        }
    }

    // 返回按钮的点击事件
    private void back() {
        imgBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}

6.修改密码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F6F6F6"
    tools:context=".Activity.ModifyPassWordActivity">

    <View
        android:id="@+id/view10"
        android:layout_width="0dp"
        android:layout_height="40dp"
        android:background="#fff"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/img_back"
        android:layout_width="15dp"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        app:layout_constraintBottom_toBottomOf="@+id/view10"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/view10"
        app:srcCompat="@drawable/back" />

    <TextView
        android:id="@+id/textView7"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="修改密码"
        android:textColor="#000"
        android:textSize="16sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="@+id/view10"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/view10" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="4dp"
        android:background="#fff"
        android:orientation="vertical"
        android:padding="20dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/view10">

        <TextView
            android:id="@+id/textView8"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="原始密码"
            android:textColor="#000"
            android:textSize="16sp"
            android:textStyle="bold" />

        <EditText
            android:id="@+id/et_old"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_marginTop="10dp"
            android:background="#fff"
            android:ems="10"
            android:hint="请输入原始密码"
            android:inputType="textPersonName"
            android:textSize="16sp" />

        <View
            android:id="@+id/view11"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginTop="5dp"
            android:background="#ccc" />

        <TextView
            android:id="@+id/textView9"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="新密码"
            android:textColor="#000"
            android:textSize="16sp"
            android:textStyle="bold" />

        <EditText
            android:id="@+id/et_new"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_marginTop="10dp"
            android:background="#fff"
            android:ems="10"
            android:hint="请输入新密码"
            android:inputType="textPersonName"
            android:textSize="16sp" />

        <View
            android:id="@+id/view12"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginTop="5dp"
            android:background="#ccc" />

        <Button
            android:id="@+id/btn_modify"
            android:layout_width="match_parent"
            android:layout_height="35dp"
            android:layout_marginTop="100dp"
            android:background="@drawable/button"
            android:text="立 即 修 改"
            android:textColor="#fff"
            android:textStyle="bold" />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

7.用户车辆管理

这段代码实现了一个名为 `CarManagementActivity` 的活动(Activity),用于展示和搜索用户的车辆信息。让我们来逐步分析其功能和结构:

1. **布局初始化和视图绑定:**
   - 在 `onCreate()` 方法中,使用 `setContentView()` 方法加载了 `activity_car_management.xml` 布局文件,并通过 `initView()` 方法初始化了界面上的控件。
   - `initView()` 方法中,绑定了返回按钮 (`imgBack`)、车牌号输入框 (`etNum`)、搜索按钮 (`imgSearch`) 和车辆信息列表 (`lv`) 的控件。

2. **显示车辆信息 (`show()` 方法):**
   - **从数据库获取车辆信息列表:**
     - 使用 `carHelper` 实例根据存储在 `SharedPreferences` 中的手机号 (`phone`),从数据库中获取用户的车辆信息列表 (`List<CarBean>`)。
     - 如果成功获取到车辆信息列表 (`carsByPhone`),则创建一个 `CarManagementAdapter` 适配器对象,并将其设置到 `ListView` (`lv`) 中显示。
     - 如果车辆信息列表为空,则显示短暂的提示信息 "暂无停车记录"。

3. **搜索车辆信息 (`search()` 方法):**
   - **搜索按钮点击事件:**
     - 设置搜索按钮 (`imgSearch`) 的点击事件监听器。
     - 获取用户输入的车牌号 (`num`)。
     - 如果车牌号为空,则显示短暂的提示信息 "请输入查询车牌号" 并调用 `show()` 方法重新显示全部车辆信息。
     - 否则,根据手机号和车牌号查询数据库中的车辆信息列表 (`List<CarBean> carsByPhoneAndCarNum`)。
     - 如果查询结果不为空且列表不为空,则创建一个新的 `CarManagementAdapter` 适配器对象,并将其设置到 `ListView` (`lv`) 中显示查询结果,并显示 "查询成功" 的提示信息。
     - 如果查询结果为空,则清空 `ListView` (`lv`) 并显示 "未查询到该车辆信息" 的提示信息。

4. **返回按钮点击事件 (`back()` 方法):**
   - **返回按钮 (`imgBack`) 的点击事件监听器,点击时结束当前活动 (`finish()`),返回上一个界面。

5. **使用到的技术和库:**
   - 使用了 `SharedPreferences` 存储用户手机号,用于从数据库中获取用户的车辆信息。
   - 使用了自定义的 `CarManagementAdapter` 适配器来填充和显示车辆信息列表。
   - 实现了简单的搜索功能,根据车牌号查询用户的车辆信息,并反馈查询结果。

总体来说,`CarManagementActivity` 提供了一个基本的用户车辆信息管理界面,用户可以查看所有车辆信息或者根据车牌号进行搜索,并且支持返回上一个界面的功能。

package com.example.parking.Activity;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.parking.Adapter.CarManagementAdapter;
import com.example.parking.Bean.CarBean;
import com.example.parking.Helper.CarHelper;
import com.example.parking.R;

import java.util.List;

public class CarManagementActivity extends AppCompatActivity {

    private ImageView imgBack;
    private EditText etNum;
    private ImageView imgSearch;
    private ListView lv;
    private CarHelper carHelper;
    private String phone;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_car_management);
        initView();
        back();
        show();
        search();
    }

    // 定义一个私有方法show()
    private void show() {
        // 调用carHelper的方法根据电话号码获取车辆信息列表
        List<CarBean> carsByPhone = carHelper.getCarsByPhone(phone);
        // 如果获取到的车辆信息列表不为空
        if (carsByPhone != null) {
            // 创建一个CarManagementAdapter适配器对象,并填充ListView
            CarManagementAdapter adapter = new CarManagementAdapter(CarManagementActivity.this, carsByPhone);
            lv.setAdapter(adapter);
        } else {
            // 如果车辆信息列表为空,则显示"暂无停车记录"的提示信息
            Toast.makeText(this, "暂无停车记录!", Toast.LENGTH_SHORT).show();
        }
    }

    // 定义一个私有方法search()
    private void search() {
        // 设置imgSearch的点击事件监听器
        imgSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 获取输入的车牌号
                String num = etNum.getText().toString();
                // 如果车牌号为空
                if (num.isEmpty()) {
                    // 显示"请输入查询车牌号"的提示信息
                    Toast.makeText(CarManagementActivity.this, "请输入查询车牌号!", Toast.LENGTH_SHORT).show();
                    // 调用show()方法
                    show();
                    return;
                }
                // 根据电话号码和车牌号查询车辆信息列表
                List<CarBean> carsByPhoneAndParkingType = carHelper.getCarsByPhoneAndCarNum(phone, num);
                // 如果查询到车辆信息列表不为空且不为空列表
                if (carsByPhoneAndParkingType != null && !carsByPhoneAndParkingType.isEmpty()) {
                    // 创建一个CarManagementAdapter适配器对象,并填充ListView
                    CarManagementAdapter adapter = new CarManagementAdapter(CarManagementActivity.this, carsByPhoneAndParkingType);
                    lv.setAdapter(adapter);
                    // 显示"查询成功"的提示信息
                    Toast.makeText(CarManagementActivity.this, "查询成功!", Toast.LENGTH_SHORT).show();
                } else {
                    // 清空ListView
                    lv.setAdapter(null);
                    // 显示"未查询到该车辆信息"的提示信息
                    Toast.makeText(CarManagementActivity.this, "未查询到该车辆信息!", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    // 定义一个私有方法back()
    private void back() {
        // 设置imgBack的点击事件监听器
        imgBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 结束当前Activity
                finish();
            }
        });
    }

    private void initView() {
        imgBack = findViewById(R.id.img_back);
        etNum = findViewById(R.id.et_num);
        imgSearch = findViewById(R.id.img_search);
        lv = findViewById(R.id.lv);
        carHelper = new CarHelper(this);
        SharedPreferences sharedPreferences = getSharedPreferences("User", Context.MODE_PRIVATE);
        phone = sharedPreferences.getString("phone", "");
    }
}

8.用户管理页面

这是一个 XML 布局文件,用于定义名为 `fragment_admin_user.xml` 的界面布局,主要用于管理员管理用户信息的功能。让我们来逐步分析其结构和布局:

1. **根布局:**
   - 根布局采用 `ConstraintLayout`,用于灵活地管理内部视图的位置和大小。
   - 设置了背景颜色为 `#F6F6F6`,使界面看起来更加舒适。

2. **顶部标题栏:**
   - 使用 `View` 元素 (`view17`) 实现了一个蓝色的顶部条,作为标题栏。
   - 在标题栏中,使用 `TextView` (`textView13`) 显示 "用户信息" 文字,文字颜色为白色,加粗,居中显示在标题栏中间。
   - 右侧使用 `ImageView` (`img_quit`) 显示了退出图标 (`quit1`),用于退出管理员用户界面。

3. **搜索栏和列表视图:**
   - 在标题栏下方是一个 `LinearLayout`,垂直排列,用于放置搜索栏和列表视图。
   - **搜索栏 (`LinearLayout`):**
     - 使用内部水平排列的 `LinearLayout`,背景为自定义的 `search_view`,用于实现搜索框的样式。
     - 包含一个 `EditText` (`et_phone`),用于输入用户手机号进行查询,背景为白色,提示用户输入类型为电话号码。
     - 右侧是一个 `ImageView` (`img_search`),显示搜索图标 (`search`),用于触发搜索操作。
   - **列表视图 (`ListView`):**
     - 位于搜索栏下方,占据剩余空间。
     - 设置了左右边距为 `10dp`,顶部边距为 `10dp`,用于控制列表视图在布局中的位置。
     - 用于显示用户信息列表,具体数据由后续的代码逻辑和适配器处理。

4. **布局属性和资源引用:**
   - 使用了 `app:layout_constraint` 系列属性来设置各个视图元素在 `ConstraintLayout` 中的约束关系,以确保它们在界面中正确布局。
   - 引用了各种资源,如颜色 (`#03A9F4`、`#fff`)、背景 (`@drawable/search_view`、`@drawable/quit1`) 和图片资源 (`@drawable/search`),用于美化界面和提供交互功能。

总体来说,这个布局文件定义了一个典型的管理员界面,包括顶部的标题栏、用户信息的搜索栏和列表视图,通过 `ConstraintLayout` 和嵌套的 `LinearLayout` 实现了界面元素的布局和排列。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F6F6F6"
    tools:context=".Admin.AdminUserFragment">

    <!-- TODO: Update blank fragment layout -->
    <View
        android:id="@+id/view17"
        android:layout_width="0dp"
        android:layout_height="40dp"
        android:background="#03A9F4"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView13"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="用户信息"
        android:textColor="#fff"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="@+id/view17"
        app:layout_constraintEnd_toEndOf="@+id/view17"
        app:layout_constraintStart_toStartOf="@+id/view17"
        app:layout_constraintTop_toTopOf="@+id/view17" />

    <ImageView
        android:id="@+id/img_quit"
        android:layout_width="20dp"
        android:layout_height="0dp"
        android:layout_marginEnd="16dp"
        android:src="@drawable/quit1"
        app:layout_constraintBottom_toBottomOf="@+id/view17"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@+id/view17" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/view17">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="35dp"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="20dp"
            android:layout_marginRight="10dp"
            android:background="@drawable/search_view"
            android:orientation="horizontal"
            android:padding="6dp">

            <EditText
                android:id="@+id/et_phone"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginLeft="4dp"
                android:layout_weight="1"
                android:background="#fff"
                android:ems="10"
                android:hint="请输入用户手机号进行查询"
                android:inputType="phone"
                android:textSize="16sp" />

            <ImageView
                android:id="@+id/img_search"
                android:layout_width="20dp"

                android:layout_height="match_parent"
                app:srcCompat="@drawable/search" />
        </LinearLayout>

        <ListView
            android:id="@+id/lv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginLeft="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginRight="10dp" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

9.通知管理

这段代码实现了一个名为 `AdminInformFragment` 的片段(Fragment),用于管理员界面发布和修改公告通知内容。让我们来逐步分析其功能和结构:

1. **布局初始化和视图绑定:**
   - 在 `onCreateView()` 方法中,使用 `LayoutInflater` 加载了 `fragment_admin_inform.xml` 布局文件,并通过 `initView(View v)` 方法初始化了片段上的控件。
   - `initView(View v)` 方法中,绑定了公告通知内容输入框 (`etInform`)、确认发布按钮 (`btnOk`) 的控件,并初始化了 `InformHelper` 实例用于访问数据库。

2. **显示公告通知内容 (`show()` 方法):**
   - **获取指定 id 的公告通知内容:**
     - 使用 `informHelper` 实例从数据库中获取指定 id (`1`) 的公告通知内容 (`InformBean informById`)。
     - 如果成功获取到公告通知内容 (`informById`),则将内容显示在公告通知内容输入框 (`etInform`) 中。

3. **修改公告通知内容 (`modify()` 方法):**
   - **确认发布按钮点击事件监听器:**
     - 设置确认发布按钮 (`btnOk`) 的点击事件监听器。
     - 获取用户输入的公告通知内容 (`inform`)。
     - 如果公告通知内容为空,则显示短暂的提示信息 "请输入公告通知内容"。
     - 否则,调用 `informHelper` 实例的 `updateInform()` 方法更新数据库中 id 为 `1` 的公告通知内容。
     - 如果更新成功 (`b` 为 `true`),显示 "发布成功" 的提示信息,并调用 `show()` 方法刷新显示最新的公告通知内容。
     - 如果更新失败,则显示 "发布失败" 的提示信息。

4. **使用到的技术和库:**
   - 使用了 `FragmentManager` 和 `FragmentTransaction` 将片段添加到管理员界面中。
   - 使用了自定义的 `InformHelper` 类来处理与公告通知内容相关的数据库操作。
   - 提供了简单的输入验证和数据库更新操作,以便管理员能够实时发布和修改公告通知。

总体来说,`AdminInformFragment` 提供了一个方便的管理员界面片段,用于发布和修改公告通知内容,通过输入框和按钮的交互,实现了简单的公告管理功能。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F6F6F6"

    tools:context=".Admin.AdminInformFragment">

    <!-- TODO: Update blank fragment layout -->
    <View
        android:id="@+id/view18"
        android:layout_width="0dp"
        android:layout_height="40dp"
        android:background="#03A9F4"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView17"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="公告通知"
        android:textColor="#fff"
        android:textSize="18sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="@+id/view18"
        app:layout_constraintEnd_toEndOf="@+id/view18"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="32dp"
        android:orientation="vertical"
        android:padding="20dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/view18">

        <TextView
            android:id="@+id/textView19"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="公告信息:"
            android:textColor="#000"
            android:textSize="18sp"
            android:textStyle="bold" />

        <EditText
            android:id="@+id/et_inform"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="20dp"
            android:background="@drawable/admin_inform"
            android:ems="10"
            android:gravity="top|left"
            android:hint="请输入公告信息"
            android:inputType="textPersonName"
            android:padding="10dp" />

        <Button
            android:id="@+id/btn_ok"
            android:layout_width="match_parent"
            android:layout_height="35dp"
            android:layout_marginTop="40dp"
            android:background="@drawable/button"
            android:text="立 即 发 布"
            android:textColor="#fff"
            android:textSize="16sp" />
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

10.车辆管理

这段代码实现了一个名为 `AdminCarFragment` 的片段(Fragment),用于管理员界面展示和搜索所有车辆信息。让我们来逐步分析其功能和结构:

1. **布局初始化和视图绑定:**
   - 在 `onCreateView()` 方法中,使用 `LayoutInflater` 加载了 `fragment_admin_car.xml` 布局文件,并通过 `initView(View v)` 方法初始化了片段上的控件。
   - `initView(View v)` 方法中,绑定了车辆类型输入框 (`etCarType`)、搜索按钮 (`imgSearch`) 和车辆信息列表 (`lv`) 的控件,并初始化了 `CarHelper` 实例用于访问数据库。

2. **显示车辆信息 (`show()` 方法):**
   - **获取所有车辆信息:**
     - 使用 `carHelper` 实例从数据库中获取所有车辆信息 (`List<CarBean> allCars`)。
     - 如果成功获取到车辆信息列表 (`allCars`),则创建一个 `AdminCarManagementAdapter` 适配器对象,并将其设置到 `ListView` (`lv`) 中显示。
     - 如果车辆信息列表为空,则显示短暂的提示信息 "暂无停车记录"。

3. **搜索车辆信息 (`search()` 方法):**
   - **搜索按钮点击事件:**
     - 设置搜索按钮 (`imgSearch`) 的点击事件监听器。
     - 获取用户输入的车辆类型 (`type`)。
     - 如果车辆类型为空,则显示短暂的提示信息 "请输入查询状态" 并调用 `show()` 方法重新显示所有车辆信息。
     - 否则,根据车辆类型从数据库中查询符合条件的车辆信息列表 (`List<CarBean> carsByParkingType`)。
     - 如果查询结果不为空且列表不为空,则创建一个新的 `AdminCarManagementAdapter` 适配器对象,并将其设置到 `ListView` (`lv`) 中显示查询结果,并显示 "查询成功" 的提示信息。
     - 如果查询结果为空,则清空 `ListView` (`lv`) 并显示 "未查询到信息" 的提示信息。

4. **点击监听器实现 (`AdminCarManagementAdapter.OnCarItemClickListener`):**
   - 实现了接口方法 `onCarItemClick()`,当车辆列表项被点击时,调用 `show()` 方法刷新 `ListView` 显示最新的车辆信息。

5. **使用到的技术和库:**
   - 使用了 `FragmentManager` 和 `FragmentTransaction` 将片段添加到管理员界面中。
   - 使用了自定义的 `AdminCarManagementAdapter` 适配器来填充和显示管理员界面中的车辆信息列表。
   - 实现了简单的搜索功能,根据车辆类型查询所有符合条件的车辆信息,并提供了点击监听器来实时更新列表。

总体来说,`AdminCarFragment` 提供了一个便捷的管理员界面片段,用于管理和搜索所有车辆信息,通过列表展示和点击监听器提供了交互和实时更新的功能。

package com.example.parking.Admin;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;

import androidx.fragment.app.Fragment;

import com.example.parking.Activity.CarManagementActivity;
import com.example.parking.Adapter.AdminCarManagementAdapter;
import com.example.parking.Adapter.CarManagementAdapter;
import com.example.parking.Bean.CarBean;
import com.example.parking.Helper.CarHelper;
import com.example.parking.R;

import java.util.List;

public class AdminCarFragment extends Fragment implements AdminCarManagementAdapter.OnCarItemClickListener {

    private EditText etCarType;
    private ImageView imgSearch;
    private ListView lv;
    private CarHelper carHelper;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_admin_car, container, false);
        initView(v);
        show();
        search();
        return v;
    }

    private void search() {
        // 设置图片点击事件监听器
        imgSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 获取车辆类型输入框中的内容
                String type = etCarType.getText().toString();
                // 判断车辆类型是否为空
                if (type.isEmpty()) {
                    // 如果为空,显示Toast提示用户输入查询状态,并调用show()方法展示所有车辆信息
                    Toast.makeText(getActivity(), "请输入查询状态!", Toast.LENGTH_SHORT).show();
                    show();
                    return;
                }
                // 根据停车类型从数据库中查询车辆信息
                List<CarBean> carsByParkingType = carHelper.getCarsByParkingType(type);
                if (carsByParkingType != null && !carsByParkingType.isEmpty()) {
                    // 如果查询到车辆信息,填充ListView并显示查询成功的Toast提示
                    AdminCarManagementAdapter adapter = new AdminCarManagementAdapter(getActivity(), carsByParkingType);
                    lv.setAdapter(adapter);
                    Toast.makeText(getActivity(), "查询成功!", Toast.LENGTH_SHORT).show();
                } else {
                    // 如果未查询到车辆信息,清空ListView并显示未查询到信息的Toast提示
                    lv.setAdapter(null);
                    Toast.makeText(getActivity(), "未查询到信息!", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    private void show() {
        // 获取所有车辆信息
        List<CarBean> allCars = carHelper.getAllCars();
        if (allCars != null) {
            // 如果有车辆信息,填充ListView并设置点击监听器,显示所有车辆信息
            AdminCarManagementAdapter adapter = new AdminCarManagementAdapter(getActivity(), allCars);
            adapter.setOnCarItemClickListener(this); // 设置点击监听器
            lv.setAdapter(adapter);
        } else {
            // 如果没有车辆信息,显示暂无停车记录的Toast提示
            Toast.makeText(getActivity(), "暂无停车记录!", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onCarItemClick() {
        // 当车辆列表项被点击时,刷新ListView显示最新车辆信息
        show();
    }

    private void initView(View v) {
        etCarType = v.findViewById(R.id.et_carType);
        imgSearch = v.findViewById(R.id.img_search);
        lv = v.findViewById(R.id.lv);
        carHelper = new CarHelper(getActivity());
    }
}

四、项目完整源码

👇👇👇👇👇快捷获取方式👇👇👇👇👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2045875.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络三级笔记--原创 风远 恒风远博

典型设备中间设备数据单元网络协议物理层中继器、集线器中继器、集线器数据位(bit) binary digit二进 制数据的缩写HUB使用了光纤、 同轴电缆、双绞 线.数据链路层网卡、网桥、交换机网桥、交换机数据帧(Frame)STP、ARQ、 SW、CSMA/CD、 PPP(点对点)、 HDLC、ATM网络层路由器、…

SQL注入(cookie、base64、dnslog外带、搜索型注入)

目录 COOKIE注入 BASE64注入 DNSLOG注入—注入判断 什么是泛解析&#xff1f; UNC路径 网上邻居 LOAD_FILE函数 搜索型注入—注入判断 本文所使用的sql注入靶场为sqli-labs-master&#xff0c;靶场资源文件已上传&#xff0c;如有需要请前往主页或以下链接下载 信安必备…

【漫谈C语言和嵌入式002】嵌入式中的大小端

在计算机科学中&#xff0c;"端序"&#xff08;Endianness&#xff09;是指多字节数据类型&#xff08;如整数或浮点数&#xff09;在内存中的存储方式。主要分为两种&#xff1a;大端模式&#xff08;Big-Endian&#xff09;和小端模式&#xff08;Little-Endian&am…

星戈瑞FITC-DXMS荧光素标记地塞米松不同方向的应用

FITC-DXMS&#xff0c;全称异硫氰基荧光素-地塞米松&#xff0c;是一种创新的科研试剂。他是由FITC-NH2的&#xff08;-NH2&#xff09;氨基与地塞米松的-OH&#xff08;羟基&#xff09;结合。它结合了地塞米松的特性和荧光素的高灵敏度标记技术&#xff0c;为医药研究、生物医…

栈与括号匹配——20、636、591、32(简中难难)

20. 有效的括号&#xff08;简单&#xff09; 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭…

springboot的学习(二):常用配置

简介 springboot的各种常用的配置。 springboot 项目是要打成jar包放到服务器上运行的。 打包 idea上使用maven打包的时候&#xff0c;会执行自动测试&#xff0c;可能会对数据库中的数据有影响&#xff0c;先点跳过测试&#xff0c;在点package。 运行 Windows上运行的…

新闻资讯小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;新闻类别管理&#xff0c;新闻信息管理&#xff0c;用户管理&#xff0c;管理员管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;新闻信息&#xff0c;我的 开发系统&a…

极市平台 | 如何通俗理解扩散模型?

本文来源公众号“极市平台”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;如何通俗理解扩散模型&#xff1f; 极市导读 还有谁没有看过diffusion的工作&#xff0c;席卷AI圈的diffusion到底是什么&#xff1f;本文作者用尽量通…

tcpdump快速入门及实践手册

tcpdump快速入门及实践手册 1. 快速入门 [1]. 基本用法 基本用法&#xff1a; tcpdump [选项 参数] [过滤器 参数] [rootkysrv1 pwe]# tcpdump -h tcpdump version 4.9.3 libpcap version 1.9.1 (with TPACKET_V3) OpenSSL 1.1.1f 31 Mar 2020 Usage: tcpdump [-aAbdDefhH…

Python爬虫使用实例

IDE&#xff1a;大部分是在PyCharm上面写的 解释器装的多 → 环境错乱 → error&#xff1a;没有配置&#xff0c;no model 爬虫可以做什么&#xff1f; 下载数据【文本/二进制数据&#xff08;视频、音频、图片&#xff09;】、自动化脚本【自动抢票、答题、采数据、评论、点…

3.2 实体-关系模型(ER模型)

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 工&#x1f497;重&#x1f497;hao&#x1f497;&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

Keycloak中授权的实现-转载

在Keycloak中实现授权&#xff0c;首先需要了解与授权相关的一些概念。授权&#xff0c;简单地说就是某个&#xff08;些&#xff09;用户或者某个&#xff08;些&#xff09;用户组&#xff08;Policy&#xff09;&#xff0c;是否具有对某个资源&#xff08;Resource&#xf…

基于SpringBoot的餐饮订单系统-计算机毕业设计源码39867

摘 要 随着现代生活节奏的加快和人们对便捷餐饮服务的需求不断增长&#xff0c;基于Spring Boot的餐饮订单系统的设计与实现成为当前研究的关键课题。本研究旨在开发一款包括首页、通知公告、餐饮资讯、餐饮菜单、商城管理等功能模块的系统&#xff0c;旨在提供便捷高效的餐饮订…

了解一下内测系统

内测系统是什么&#xff1f; 在软件或应用程序开发的过程中&#xff0c;供开发人员进行测试和调试的系统。 内测系统的作用是什么&#xff1f; 达到让用户使用游戏或者软件的时候体验感更好、减少风险、方便开发者更好的找到并解决自己软件中的问题。测试好后的app可以将自己的…

C ++ 也可以搭建Web?高性能的 C++ Web 开发框架 CPPCMS + MySQL 实现快速入门案例

什么是CPPCMS&#xff1f; CppCMS 是一个高性能的 C Web 开发框架&#xff0c;专为构建快速、动态的网页应用而设计&#xff0c;特别适合高并发和低延迟的场景。其设计理念类似于 Python 的 Django 或 Ruby on Rails&#xff0c;但针对 C 提供了更细粒度的控制和更高效的性能。…

Linux--传输层协议UDP

目录 传输层 再谈端口号 端口号范围划分 认识知名端口号(Well-Know Port Number) 两个问题 UDP 协议 UDP 协议端格式 UDP 的特点 面向数据报 UDP 的缓冲区 UDP 使用注意事项 基于 UDP 的应用层协议 进一步理解UDP协议 传输层 负责数据能够从发送端传输接收端. 再谈…

STM32F407ZET6使用LCD(9341)

1.原理图 屏幕是中景园2.8寸液晶屏&#xff0c;9341驱动不带触摸屏版本 2.STM32CUBEMX配置 3.编写驱动程序

【全国大学生电子设计竞赛】2021年K题

&#x1f970;&#x1f970;全国大学生电子设计大赛学习资料专栏已开启&#xff0c;限时免费&#xff0c;速速收藏~

02 网络编程-UDP用户数据包协议

目录 一、UDP简介 二、UDP协议的通信流程 三、UDP相关API接口 &#xff08;1&#xff09;创建套接字-socket() &#xff08;2&#xff09;地址信息结构体sockaddr_in{} &#xff08;3&#xff09;地址转换接口 &#xff08;4&#xff09;发送消息sendto() &#xff08;…

谁偷偷看了你的网站?这两款统计工具告诉你!小白易上手~

前两天&#xff0c;上线了一个知识库网站&#xff1a;花了一天时间&#xff0c;搭了个专属知识库&#xff0c;终于上线了&#xff0c;手把手教&#xff0c;不信你学不会。 想知道这个网站的流量如何&#xff0c;怎么搞&#xff1f; 网站流量统计分析工具&#xff0c;了解下&a…