2025.3.15(石家庄地铁购票app)

昨天晚上忘记发了,今天我把昨天写的石家庄地铁购票的app发来
创建一个空项目,因为不需要连接数据库,所以就不用导入jar包,
然后同步成功后开始写项目,这是我的项目路径:

然后开始写(JDBCUtils和utils可以不写,因为不连接数据库),总体来说还是简单的,
主要就一个MainActivity和activity_main.xml
MainActivity如下

点击查看代码
package com.example.subway;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    private Spinner startStationSpinner, endStationSpinner;
    private TextView resultText;

    // 石家庄地铁线路数据
    private Map<String, List<String>> metroLines = new HashMap<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化地铁线路数据
        initMetroLines();

        // 初始化UI组件
        startStationSpinner = findViewById(R.id.start_station_spinner);
        endStationSpinner = findViewById(R.id.end_station_spinner);
        resultText = findViewById(R.id.result_text);

        // 设置起点站和终点站的下拉选项
        setSpinnerAdapter();

        // 添加起点站选择监听器
        startStationSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String startStation = parent.getItemAtPosition(position).toString();
                // 这里可以添加逻辑处理起点站选择后的操作
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                // 未选择时的处理
            }
        });

        // 添加终点站选择监听器
        endStationSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String endStation = parent.getItemAtPosition(position).toString();
                // 这里可以添加逻辑处理终点站选择后的操作
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                // 未选择时的处理
            }
        });
    }

    // 初始化石家庄地铁线路数据
    private void initMetroLines() {
        // 1号线站点
        List<String> line1 = new ArrayList<>();
        line1.add("西王");
        line1.add("时光街");
        line1.add("长城桥");
        line1.add("和平医院");
        line1.add("烈士陵园");
        line1.add("新百广场");
        line1.add("解放广场");
        line1.add("平安大街");
        line1.add("北国商城");
        line1.add("博物馆");
        line1.add("体育场");
        line1.add("北宋");
        line1.add("谈固");
        line1.add("朝晖桥");
        line1.add("白佛");
        line1.add("留村");
        line1.add("火炬广场");

        // 2号线站点
        List<String> line2 = new ArrayList<>();
        line2.add("柳辛庄");
        line2.add("嘉华路");
        line2.add("高柱");
        line2.add("西三庄");
        line2.add("柏林庄");
        line2.add("市庄");
        line2.add("市二中");
        line2.add("北国商城");
        line2.add("长安公园");
        line2.add("建和桥");
        line2.add("义堂");
        line2.add("铁道大学");
        line2.add("柳辛庄");
        line2.add("福泽");
        line2.add("园博园");
        line2.add("商务中心");
        line2.add("会展中心");
        line2.add("东庄");
        line2.add("西庄");
        line2.add("洨河大道");

        // 3号线站点
        List<String> line3 = new ArrayList<>();
        line3.add("西三庄");
        line3.add("柏林庄");
        line3.add("市二中");
        line3.add("新百广场");
        line3.add("石家庄站");
        line3.add("槐安桥");
        line3.add("东里");
        line3.add("槐中路");
        line3.add("裕华路");
        line3.add("南位");
        line3.add("仓丰路留村");
        line3.add("塔坛");
        line3.add("汇通路");
        line3.add("孙村");
        line3.add("塔冢");
        line3.add("东王");
        line3.add("南王");
        line3.add("位同");
        line3.add("东二环南路");
        line3.add("西仰陵");
        line3.add("中仰陵");
        line3.add("南豆");
        line3.add("太行南大街");
        line3.add("乐乡");

        metroLines.put("1号线", line1);
        metroLines.put("2号线", line2);
        metroLines.put("3号线", line3);
    }

    // 设置Spinner适配器
    private void setSpinnerAdapter() {
        // 合并所有站点到一个列表
        List<String> allStations = new ArrayList<>();
        for (List<String> line : metroLines.values()) {
            allStations.addAll(line);
        }

        // 去重
        List<String> uniqueStations = new ArrayList<>();
        for (String station : allStations) {
            if (!uniqueStations.contains(station)) {
                uniqueStations.add(station);
            }
        }

        // 创建适配器
        ArrayAdapter<String> adapter = new ArrayAdapter<>(
                this, android.R.layout.simple_spinner_item, uniqueStations);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        // 设置适配器到Spinner
        startStationSpinner.setAdapter(adapter);
        endStationSpinner.setAdapter(adapter);
    }

    // 购票按钮点击事件
    public void onBuyTicketClick(View view) {
        String startStation = startStationSpinner.getSelectedItem().toString();
        String endStation = endStationSpinner.getSelectedItem().toString();
        String quantityStr = ((android.widget.EditText) findViewById(R.id.ticket_quantity)).getText().toString();

        // 验证输入
        if (startStation.equals(endStation)) {
            resultText.setText("起点站和终点站不能相同");
            return;
        }

        if (quantityStr.isEmpty() || Integer.parseInt(quantityStr) <= 0) {
            resultText.setText("请输入有效的购票数量");
            return;
        }

        int quantity = Integer.parseInt(quantityStr);

        // 计算票价
        double price = calculatePrice(startStation, endStation);

        if (price == -1) {
            resultText.setText("无法计算票价,请检查站点选择");
            return;
        }

        // 显示购票结果
        resultText.setText("购票成功!\n票价: " + price + "元\n购票数量: " + quantity + "张\n总价: " + (price * quantity) + "元");
    }

    // 计算票价
    private double calculatePrice(String startStation, String endStation) {
        try {
            // 查找起点站和终点站所在的线路
            String startLine = findLine(startStation);
            String endLine = findLine(endStation);

            if (startLine == null || endLine == null) {
                return -1; // 站点不存在
            }

            // 如果起点和终点在同一线路
            if (startLine.equals(endLine)) {
                List<String> line = metroLines.get(startLine);
                int startIndex = line.indexOf(startStation);
                int endIndex = line.indexOf(endStation);

                int stationCount = Math.abs(endIndex - startIndex);

                // 计算票价:每三站一元,不足三站按一元算
                int price = (stationCount + 2) / 3; // 向上取整

                return price;
            } else {
                // 跨线路计算:找到换乘站并计算最低票价
                List<String> commonStations = findCommonStations(startLine, endLine);

                if (commonStations.isEmpty()) {
                    return -1; // 无法换乘
                }

                double minPrice = Double.MAX_VALUE;

                // 遍历所有换乘站,找到最低票价
                for (String commonStation : commonStations) {
                    // 计算第一段(起点到换乘站)
                    List<String> line1 = metroLines.get(startLine);
                    int startIndex = line1.indexOf(startStation);
                    int transferIndex = line1.indexOf(commonStation);
                    int firstSegment = Math.abs(transferIndex - startIndex);

                    // 计算第二段(换乘站到终点)
                    List<String> line2 = metroLines.get(endLine);
                    int endIndex = line2.indexOf(endStation);
                    int transferIndex2 = line2.indexOf(commonStation);
                    int secondSegment = Math.abs(endIndex - transferIndex2);

                    // 计算两段的票价
                    int firstPrice = (firstSegment + 2) / 3;
                    int secondPrice = (secondSegment + 2) / 3;
                    double totalPrice = firstPrice + secondPrice;

                    // 更新最低票价
                    if (totalPrice < minPrice) {
                        minPrice = totalPrice;
                    }
                }

                return minPrice;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    // 查找站点所在的线路
    private String findLine(String station) {
        for (Map.Entry<String, List<String>> entry : metroLines.entrySet()) {
            if (entry.getValue().contains(station)) {
                return entry.getKey();
            }
        }
        return null;
    }

    // 查找两线的换乘站
    private List<String> findCommonStations(String line1, String line2) {
        List<String> commonStations = new ArrayList<>();
        List<String> line1Stations = metroLines.get(line1);
        List<String> line2Stations = metroLines.get(line2);

        for (String station : line1Stations) {
            if (line2Stations.contains(station)) {
                commonStations.add(station);
            }
        }

        return commonStations;
    }
}
点击查看代码
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">

        <!-- 起点站选择 -->
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="起点站"
            android:textSize="18sp"
            android:layout_marginTop="20dp"/>

        <Spinner
            android:id="@+id/start_station_spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <!-- 终点站选择 -->
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="终点站"
            android:textSize="18sp"
            android:layout_marginTop="20dp"/>

        <Spinner
            android:id="@+id/end_station_spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <!-- 购票数量 -->
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="购票数量"
            android:textSize="18sp"
            android:layout_marginTop="20dp"/>

        <EditText
            android:id="@+id/ticket_quantity"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="number"
            android:hint="请输入购票数量"/>

        <!-- 购票按钮 -->
        <Button
            android:id="@+id/buy_ticket_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="立即购票"
            android:layout_marginTop="20dp"
            android:onClick="onBuyTicketClick"/>

        <!-- 结果显示 -->
        <TextView
            android:id="@+id/result_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:layout_marginTop="20dp"/>

    </LinearLayout>
</ScrollView>
然后是软件测试: ![](https://img2024.cnblogs.com/blog/3473654/202503/3473654-20250315195314867-962168670.png) 软件在这里下载: https://github.com/cwk2017-d/cautious-spoon
posted on 2025-03-15 19:38  睡觉时候不困  阅读(19)  评论(0)    收藏  举报