change code

This commit is contained in:
2026-01-10 16:54:32 +09:00
parent b6d11fa206
commit 517f378388
8 changed files with 146 additions and 111 deletions

View File

@@ -0,0 +1,17 @@
package com.example.curation_train_app
import android.content.Context
object FollowSettings {
fun loadLines(context: Context): List<String> {
val prefs = context.getSharedPreferences("follow", Context.MODE_PRIVATE)
val set = prefs.getStringSet("lines", emptySet()) ?: emptySet()
return set.toList()
}
fun saveLines(context: Context, lines: List<String>) {
val prefs = context.getSharedPreferences("follow", Context.MODE_PRIVATE)
prefs.edit().putStringSet("lines", lines.toSet()).apply()
}
}

View File

@@ -2,33 +2,27 @@ package com.example.curation_train_app
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Button import android.widget.*
import android.widget.EditText
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.example.curation_train_app.ai.AiClient import com.example.curation_train_app.ai.AiClient
import com.example.curation_train_app.CharacterSettings import com.example.curation_train_app.CharacterSettings
import retrofit2.Retrofit
import okhttp3.ResponseBody import okhttp3.ResponseBody
import org.jsoup.Jsoup import org.jsoup.Jsoup
import retrofit2.Retrofit
import retrofit2.converter.scalars.ScalarsConverterFactory import retrofit2.converter.scalars.ScalarsConverterFactory
import retrofit2.http.GET import retrofit2.http.GET
import retrofit2.Call import retrofit2.Call
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
// --- キャラ初期画像 ---
val charId = CharacterSettings.loadCharacter(this) val charId = CharacterSettings.loadCharacter(this)
val imageView = findViewById<ImageView>(R.id.imageCharacter) val imageView = findViewById<ImageView>(R.id.imageCharacter)
@@ -43,61 +37,56 @@ class MainActivity : ComponentActivity() {
"hiyori" -> R.drawable.hiyori_normal "hiyori" -> R.drawable.hiyori_normal
else -> R.drawable.reimu_normal else -> R.drawable.reimu_normal
} }
imageView.setImageResource(drawableId) imageView.setImageResource(drawableId)
// ----- キャラ応答ボタン -----
val btn = findViewById<Button>(R.id.btnTestReply) val btn = findViewById<Button>(R.id.btnTestReply)
val inputText = findViewById<EditText>(R.id.inputText) val inputText = findViewById<EditText>(R.id.inputText)
val inputCharacter = findViewById<EditText>(R.id.inputCharacter)
val textResult = findViewById<TextView>(R.id.textTestResult)
val commentView = findViewById<TextView>(R.id.textCharacterComment) val commentView = findViewById<TextView>(R.id.textCharacterComment)
btn.setOnClickListener { btn.setOnClickListener {
val text = inputText.text.toString() val text = inputText.text.toString()
val charId = CharacterSettings.loadCharacter(this) // ← 入力欄ではなく設定から読む val charId = CharacterSettings.loadCharacter(this)
val infoType = InfoClassifier.classify(text) val infoType = InfoClassifier.classify(text)
Thread { Thread {
val result = CharacterReplyManager().replyWithAI(charId, text, infoType) val result = CharacterReplyManager().replyWithAI(charId, text, infoType)
runOnUiThread { runOnUiThread {
commentView.text = result.text commentView.text = result.text
updateCharacterExpression(charId, result.emotion) updateCharacterExpression(charId, result.emotion)
} }
}.start() }.start()
} }
// --- 運行情報 & RSS 読み込み ---
loadTraffic() loadTraffic()
loadRss() loadRss()
// --- RecyclerView 初期設定 ---
val recyclerNews = findViewById<RecyclerView>(R.id.recyclerNews) val recyclerNews = findViewById<RecyclerView>(R.id.recyclerNews)
recyclerNews.layoutManager = recyclerNews.layoutManager = LinearLayoutManager(this)
LinearLayoutManager(this)
// 路線設定画面へ遷移
// ▲ リリース枠 ▲
// ▼ 地域セレクト画面へ ▼
val btnOpenRegion = findViewById<TextView>(R.id.textFavorite) val btnOpenRegion = findViewById<TextView>(R.id.textFavorite)
btnOpenRegion.setOnClickListener { btnOpenRegion.setOnClickListener {
val intent = Intent(this, RegionSelectActivity::class.java) val intent = Intent(this, RegionSelectActivity::class.java)
startActivity(intent) startActivity(intent)
} }
// ▲ 地域セレクト画面へ ▲
// ▼ キャラ画像の初期配置 ▼
applyCharacterLayoutDefault() applyCharacterLayoutDefault()
// 詳細画面へ遷移
val titleView = findViewById<TextView>(R.id.textTitle)
titleView.setOnClickListener {
val text = titleView.tag as? String ?: "(詳細情報なし)"
val intent = Intent(this, TrafficDetailActivity::class.java)
intent.putExtra("text", text)
startActivity(intent)
}
} }
// ▼ キャラ画像の位置調整関数 ▼ // -----------------------------
private fun applyCharacterLayoutDefault() { private fun applyCharacterLayoutDefault() {
val img = findViewById<ImageView>(R.id.imageCharacter) val img = findViewById<ImageView>(R.id.imageCharacter)
val scale = resources.displayMetrics.density val scale = resources.displayMetrics.density
@@ -115,10 +104,10 @@ class MainActivity : ComponentActivity() {
lp.topMargin = (offsetYdp * scale).toInt() lp.topMargin = (offsetYdp * scale).toInt()
img.layoutParams = lp img.layoutParams = lp
img.requestLayout()
} }
// ▼ RSS 読み込み ▼ // -----------------------------
private fun loadRss() { private fun loadRss() {
Thread { Thread {
try { try {
@@ -144,6 +133,8 @@ class MainActivity : ComponentActivity() {
}.start() }.start()
} }
// -----------------------------
private fun loadTraffic() { private fun loadTraffic() {
Thread { Thread {
try { try {
@@ -153,74 +144,50 @@ class MainActivity : ComponentActivity() {
.build() .build()
val client = retrofit.create(HtmlClient::class.java) val client = retrofit.create(HtmlClient::class.java)
val response = client.getHtml().execute() val response = client.getHtml().execute()
val html = response.body()?.string() ?: "" val html = response.body()?.string() ?: return@Thread
val doc = Jsoup.parse(html) val doc = Jsoup.parse(html)
val items = mutableListOf<NewsItem>() val lines = doc.select("div.jisyo")
val list = doc.select("div.jisyo") // ← 運行情報の1ブロック
for (block in list) {
val title = block.select("h2.jisyo_title").text()
val body = block.select("div.jisyo_contents p").text()
if (title.isNotEmpty()) {
items.add(
NewsItem(
company = "JR西日本",
title = title,
body = body
)
)
}
}
// --- 総合判定 ---
var hasSuspension = false
var hasDelay = false var hasDelay = false
var hasSuspension = false
var hasInfo = false var hasInfo = false
for (item in items) { val items = mutableListOf<NewsItem>()
when (item.company) { // ← company に status 入れてるよね?
"運転見合わせ" -> hasSuspension = true for (line in lines) {
"遅延" -> hasDelay = true val title = line.select("h2").text()
"情報あり" -> hasInfo = true val body = line.select("p.gaiyo").text()
} val classes = line.classNames()
if (classes.contains("stop")) hasSuspension = true
if (classes.contains("delay")) hasDelay = true
if (classes.contains("info")) hasInfo = true
} }
val resultTitle = when { val statusText = when {
hasSuspension -> "運転見合わせがあります" hasSuspension -> "運転見合わせ"
hasDelay -> "遅延が発生しています" hasDelay -> "遅延"
hasInfo -> "運行に関するお知らせがあります" hasInfo -> "情報あり"
else -> "平常運転" else -> "平常運転"
} }
runOnUiThread { runOnUiThread {
// 最上段のテキスト書き換え val statusView = findViewById<TextView>(R.id.trafficStatus)
val titleView = findViewById<TextView>(R.id.textTitle) statusView.text = "設定した路線:$statusText"
titleView.text = "近畿エリア:$resultTitle"
// RecyclerView を更新
val recycler = findViewById<RecyclerView>(R.id.recyclerNews)
recycler.adapter = NewsAdapter(items)
} }
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
}.start() }.start()
} }
// -----------------------------
fun emotionToExpression(type: EmotionType): String { fun emotionToExpression(type: EmotionType): String {
return when (type) { return when (type) {
@@ -236,39 +203,19 @@ class MainActivity : ComponentActivity() {
} }
fun updateCharacterExpression(charId: String, type: EmotionType) { fun updateCharacterExpression(charId: String, type: EmotionType) {
val imageView = findViewById<ImageView>(R.id.imageCharacter) val imageView = findViewById<ImageView>(R.id.imageCharacter)
// 感情 → 表情名("happy"など)
val expression = emotionToExpression(type) val expression = emotionToExpression(type)
val resName = "${charId}_${expression}"
// charId("reimu") と合わせて画像ファイル名を作る
val resName = "${charId}_${expression}" // → "reimu_happy"
val resId = resources.getIdentifier(resName, "drawable", packageName) val resId = resources.getIdentifier(resName, "drawable", packageName)
if (resId != 0) { if (resId != 0)
imageView.setImageResource(resId) imageView.setImageResource(resId)
} else { else {
// 画像がない場合は normal に戻す
val normalId = resources.getIdentifier("${charId}_normal", "drawable", packageName) val normalId = resources.getIdentifier("${charId}_normal", "drawable", packageName)
imageView.setImageResource(normalId) imageView.setImageResource(normalId)
} }
} }
fun infoTypeToEmotion(info: InfoType): EmotionType {
return when (info) {
InfoType.DELAY -> EmotionType.WORRY
InfoType.SUSPENSION -> EmotionType.ANGRY
InfoType.REVISION -> EmotionType.THINK
InfoType.CONSTRUCTION -> EmotionType.THINK
InfoType.EVENT -> EmotionType.HAPPY
InfoType.WEATHER -> EmotionType.CONFUSED
InfoType.NEW_TRAIN -> EmotionType.SURPRISED
else -> EmotionType.NORMAL
}
}
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
@@ -278,7 +225,7 @@ class MainActivity : ComponentActivity() {
val drawableId = when (charId) { val drawableId = when (charId) {
"reimu" -> R.drawable.reimu_normal "reimu" -> R.drawable.reimu_normal
"marisa" -> R.drawable.marisa_normal "marisa" -> R.drawable.marisa_normal
"flan" -> R.drawable.flandre_normal "flandre" -> R.drawable.flandre_normal
"sanae" -> R.drawable.sanae_normal "sanae" -> R.drawable.sanae_normal
"akane" -> R.drawable.akane_normal "akane" -> R.drawable.akane_normal
"momoka" -> R.drawable.momoka_normal "momoka" -> R.drawable.momoka_normal
@@ -289,7 +236,6 @@ class MainActivity : ComponentActivity() {
imageView.setImageResource(drawableId) imageView.setImageResource(drawableId)
} }
} }

View File

@@ -33,6 +33,16 @@ class RegionSelectActivity : ComponentActivity() {
finish() finish()
} }
setupRegionButton(R.id.btnNorth, "hokkaido")
setupRegionButton(R.id.btnTohoku, "tohoku")
setupRegionButton(R.id.btnKanto, "kanto")
setupRegionButton(R.id.btnChubu, "chubu")
setupRegionButton(R.id.btnKansai, "kansai")
setupRegionButton(R.id.btnChugoku, "chugoku")
setupRegionButton(R.id.btnShikoku, "shikoku")
setupRegionButton(R.id.btnKyushu, "kyushu")
reimuButton.setOnClickListener { selectCharacter("reimu") } reimuButton.setOnClickListener { selectCharacter("reimu") }
marisaButton.setOnClickListener { selectCharacter("marisa") } marisaButton.setOnClickListener { selectCharacter("marisa") }
flandreButton.setOnClickListener { selectCharacter("flandre") } flandreButton.setOnClickListener { selectCharacter("flandre") }
@@ -41,8 +51,18 @@ class RegionSelectActivity : ComponentActivity() {
momokaButton.setOnClickListener { selectCharacter("momoka") } momokaButton.setOnClickListener { selectCharacter("momoka") }
sayakaButton.setOnClickListener { selectCharacter("sayaka") } sayakaButton.setOnClickListener { selectCharacter("sayaka") }
hiyoriButton.setOnClickListener { selectCharacter("hiyori") } hiyoriButton.setOnClickListener { selectCharacter("hiyori") }
}
private fun setupRegionButton(buttonId: Int, region: String) {
val btn = findViewById<Button>(buttonId)
btn.setOnClickListener {
val intent = Intent(this, LineSelectActivity::class.java)
intent.putExtra("region", region)
startActivity(intent)
// ❌ これは絶対削除!
// CharacterSettings.saveCharacter(this, "reimu")
}
// ❌ これは絶対削除!
// CharacterSettings.saveCharacter(this, "reimu")
} }
} }

View File

@@ -11,3 +11,6 @@ interface RssClient {
} }

View File

@@ -0,0 +1,18 @@
package com.example.curation_train_app
import android.os.Bundle
import android.widget.TextView
import androidx.activity.ComponentActivity
class TrafficDetailActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_traffic_detail)
val text = intent.getStringExtra("text") ?: ""
val tv = findViewById<TextView>(R.id.textDetail)
tv.text = text
}
}

View File

@@ -0,0 +1,7 @@
package com.example.curation_train_app
data class TrafficItem(
val title: String,
val desc: String,
val status: String
)

View File

@@ -18,6 +18,17 @@
android:background="@drawable/comment_background_white" android:background="@drawable/comment_background_white"
android:elevation="2dp"> android:elevation="2dp">
<TextView
android:id="@+id/trafficStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="読み込み中…"
android:textSize="18sp"
android:textStyle="bold"
android:layout_margin="12dp"
/>
<TextView <TextView
android:id="@+id/textTitle" android:id="@+id/textTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -26,6 +37,7 @@
android:textSize="18sp" android:textSize="18sp"
android:textStyle="bold" android:textStyle="bold"
android:paddingBottom="8dp" android:paddingBottom="8dp"
android:visibility="gone"
/> />
<TextView <TextView

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<TextView
android:id="@+id/textDetail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp"/>
</ScrollView>