質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

2回答

538閲覧

android studioでTodoリストの作成

ottosay

総合スコア4

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2023/12/09 19:09

編集2023/12/11 17:22

今android studioでTodoリストを作成しています

削除ボタンの増設について、聞きたいことがあります。

以下がTodo.javaです。

package com.example.studytodo; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentManager; import android.os.Bundle; import android.util.Log; public class Todo extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.todo); FragmentManager fm = getSupportFragmentManager(); fm.setFragmentResultListener(TodoFragment.REQUEST_KEY, this, (rkey,result)->{ // TodoFragment が back したら何する? Log.d("MainActivity", "backed todofragment."); }); fm.beginTransaction() .replace(R.id.fragment_container_view, new TodoFragment()) .commit(); } }

また、次がTodoFragment.javaです

package com.example.studytodo; import androidx.annotation.*; import androidx.fragment.app.*; import androidx.recyclerview.widget.*; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.*; import android.widget.*; import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; public class TodoFragment extends Fragment { static final String REQUEST_KEY = "TodoFragment"; private List<Task> taskList = new ArrayList<>(); public TodoFragment() { super(R.layout.fragment_todo); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); TaskAdapter taskAdapter = new TaskAdapter(); RecyclerView recyclerView = view.findViewById(R.id.recyclerViewTasks); recyclerView.setAdapter(taskAdapter); FragmentManager fm = getChildFragmentManager(); fm.setFragmentResultListener(AddTaskFragment.REQUEST_KEY, getViewLifecycleOwner(), (rkey, result) -> { taskAdapter.addTask((Task) result.getSerializable(AddTaskFragment.RESULTKEY_TASK)); }); fm.setFragmentResultListener(AddTaskFragment.REQUEST_KEY, getViewLifecycleOwner(), (rkey, result) -> { Task addedTask = (Task) result.getSerializable(AddTaskFragment.RESULTKEY_TASK); // TaskAdapterに追加 taskAdapter.addTask(addedTask); // TodoFragment内のリストにも追加 taskList.add(addedTask); }); ImageButton btBackTodo = view.findViewById(R.id.btBackTodo); btBackTodo.setOnClickListener(v -> { Toast.makeText(getContext(), "戻るボタンがクリックされました", Toast.LENGTH_SHORT).show(); getParentFragmentManager().setFragmentResult(REQUEST_KEY, new Bundle()); //(MainActivity に)通知 Intent intent = new Intent(requireContext(), MainActivity.class); startActivity(intent); requireActivity().finish(); }); ImageButton addButton = view.findViewById(R.id.btAdd); addButton.setOnClickListener(v -> { Toast.makeText(getContext(), "追加ボタンがクリックされました", Toast.LENGTH_SHORT).show(); new AddTaskFragment().show(fm, null); //ダイアログ表示 }); } } class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.ViewHolder> { private final List<Task> taskList = new ArrayList<>(); void addTask(Task task) { Log.d("TaskAdded", "Task added: " + task); taskList.add(task); notifyItemInserted(taskList.size()-1); } void removeTask(int position) { taskList.remove(position); notifyItemRemoved(position); notifyItemRangeChanged(position, taskList.size()); } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { return new ViewHolder(parent); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { Log.d("AdapterDebug", "onBindViewHolder called for position: " + position); holder.bind(taskList.get(position)); } @Override public int getItemCount() { return taskList.size(); } static class ViewHolder extends RecyclerView.ViewHolder { private final TextView taskName, dateTime; public ViewHolder(@NonNull ViewGroup parent) { super(LayoutInflater.from(parent.getContext()).inflate(R.layout.task_item, parent, false)); taskName = itemView.findViewById(R.id.taskNameTextView); dateTime = itemView.findViewById(R.id.dateTimeTextView); } void bind(Task task) { taskName.setText(task.taskName); dateTime.setText(task.getDateTime()); } } } class Task implements Serializable { static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm"); final String taskName; final LocalDateTime dateTime; public Task(String taskName, LocalDateTime dateTime) { this.taskName = taskName; this.dateTime = dateTime; } String getDateTime() { return formatter.format(dateTime); } @Override public String toString() { return taskName + " at " + getDateTime(); } }

次がAddTaskFragment.javaです

package com.example.studytodo; import androidx.annotation.*; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.DialogFragment; import android.app.*; import android.os.Bundle; import android.view.*; import android.widget.*; import java.time.*; public class AddTaskFragment extends DialogFragment { static final String REQUEST_KEY = "AddTaskFragment"; static final String RESULTKEY_TASK = "task"; private EditText nameView, datetimeView; private LocalDateTime datetime; @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { View view = LayoutInflater.from(requireContext()).inflate(R.layout.fragment_add_task, null); datetime = LocalDateTime.now(); nameView = view.findViewById(R.id.editTextTaskName); datetimeView = view.findViewById(R.id.editTextDateTime); datetimeView.setOnClickListener(v -> showDatePickerDialog()); return new AlertDialog.Builder(requireContext()) .setTitle("Add Task") .setView(view) .setPositiveButton("保存", (d, w) -> { String name = nameView.getText().toString(); Bundle result = new Bundle(); result.putSerializable(RESULTKEY_TASK, new Task(name, datetime)); getParentFragmentManager().setFragmentResult(REQUEST_KEY, result); dismiss(); }) .setNegativeButton("キャンセル", (d, w) -> dismiss()) .create(); } private void showDatePickerDialog() { DatePickerDialog datePickerDialog = new DatePickerDialog(getContext(), (v, y, m, d) -> { //m: 0-11 datetime = datetime.with(LocalDate.of(y, m+1, d)); //m: 1-12 showTimePickerDialog(); }, datetime.getYear(), datetime.getMonthValue()-1, datetime.getDayOfMonth()); //m: 0-11 datePickerDialog.show(); } private void showTimePickerDialog() { TimePickerDialog timePickerDialog = new TimePickerDialog(getContext(), (v, h, m) -> { datetime = datetime.with(LocalTime.of(h, m)); datetimeView.setText(Task.formatter.format(datetime)); }, datetime.getHour(), datetime.getMinute(), true); timePickerDialog.show(); } }

次がTodoViewModel.javaです

package com.example.studytodo; import androidx.lifecycle.ViewModel; import androidx.lifecycle.MutableLiveData; public class TodoViewModel extends ViewModel { private MutableLiveData<Task> addedTask = new MutableLiveData<>(); public void setAddedTask(Task task) { addedTask.setValue(task); } public MutableLiveData<Task> getAddedTask() { return addedTask; } }

task_item.xml

<!-- task_item.xml --> <androidx.constraintlayout.widget.ConstraintLayout 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:padding="10dp"> <TextView android:id="@+id/taskNameTextView" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/dateTimeTextView" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/taskNameTextView" /> <ImageButton android:id="@+id/deleteButton" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/dateTimeTextView" android:src="@drawable/baseline_clear_24" android:background="?android:attr/selectableItemBackgroundBorderless" /> </androidx.constraintlayout.widget.ConstraintLayout>

試したこと

前回回答していただいたときにFragmentを利用したら簡単にできるとコード付きで教えてもらったことで、Todoリストにタスクを追加することはできました。
今現在はタスクを追加した後に削除マークを付け、押すと追加したタスクを削除して画面から消えるようにしたいと考えています。
また、戻ってからまたtodo.xmlの画面に遷移すると追加したはずのタスクが消えてしまいます。。。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2023/12/09 19:51

// TODO: taskList に追加する処理を実装 のところを実装する必要があるのでは…。
ottosay

2023/12/09 19:58

すみません、具体的にどのようにしたらいいか教えていただけますでしょうか。
hoshi-takanori

2023/12/09 21:12 編集

よく見たら、onActivityResult の方には何か書いてありますが、AddTaskActivity への遷移は addTaskLauncher を使ってるので、onActivityResult は呼ばれないですね。 あと、AddTaskActivity の saveTask メソッドで getParent を使って todoActivity.addTask を呼んでますが、そういうことをしてはいけません。 それから、Todo の setupBackButton メソッドで MainActivity を startActivity してますが、これは元の MainActivity に戻るのではなく、新しく MainActivity を開くことになります。
ottosay

2023/12/09 21:31

詳しく教えていただきありがとうございます。 一度教えてくださった場所を修正してみたいと思います
ottosay

2023/12/09 22:04

新しくMainActivityを開いてしまう件については以下のソースコードで治ったのかなと思います。 private void setupAddButton() { ImageButton btAdd = findViewById(R.id.btAdd); btAdd.setOnClickListener(v -> { // 追加ボタンがクリックされた時の処理 Toast.makeText(Todo.this, "追加ボタンがクリックされました", Toast.LENGTH_SHORT).show(); // アクティビティを終了して前の画面に戻る finish(); }); }
ottosay

2023/12/09 22:38

何度もすみません、あれから何度か修正し、アプリで実行しているのですがやはりRecyclerViewに追加されません。 こういう風にしたらいいよなど詳しく教えてもらうことは可能でしょうか?
jimbe

2023/12/10 05:11

コードはファイル毎にコードのマークダウン(```だけの行で前後を囲む)を使用してください。 質問の変化については、コメントでなく質問に追加編集してください。
jimbe

2023/12/10 05:40 編集

ここまで作られていて今更と思われるかもしれませんが、 Fragment の利用を考えたほうがよいと思います。 AddTaskActivity なんて DialogFragment で十分でしょう。
ottosay

2023/12/10 10:17

色々と教えて頂きありがとうございます。 修正してみます。
guest

回答2

0

ベストアンサー

コード量的に書き込めるか確かめるだけのつもりが操作誤って書き込んでしまいました汗
やはり全部は書き込めなかったので java コードだけ載せ、レイアウト等を含めた一通りは github に入れました。
Todo や AddTask をフラグメントにしています。

MainActivity.java

java

1import androidx.appcompat.app.AppCompatActivity; 2import androidx.fragment.app.FragmentManager; 3 4import android.os.Bundle; 5import android.util.Log; 6 7public class MainActivity extends AppCompatActivity { 8 @Override 9 protected void onCreate(Bundle savedInstanceState) { 10 super.onCreate(savedInstanceState); 11 setContentView(R.layout.activity_main); 12 13 FragmentManager fm = getSupportFragmentManager(); 14 fm.setFragmentResultListener(TodoFragment.REQUEST_KEY, this, (rkey,result)->{ 15 /*TodoFragment が back したら何する? */ 16 Log.d("MainActivity", "backed todofragment."); 17 }); 18 19 fm.beginTransaction() 20 .replace(R.id.fragment_container_view, new TodoFragment()) 21 .commit(); 22 } 23}

TodoFragment.java (TodoAdapter,Task クラスを含む)

java

1import androidx.annotation.*; 2import androidx.fragment.app.*; 3import androidx.recyclerview.widget.*; 4 5import android.os.Bundle; 6import android.util.Log; 7import android.view.*; 8import android.widget.*; 9 10import java.io.Serializable; 11import java.time.LocalDateTime; 12import java.time.format.DateTimeFormatter; 13import java.util.*; 14 15public class TodoFragment extends Fragment { 16 static final String REQUEST_KEY = "TodoFragment"; 17 18 public TodoFragment() { 19 super(R.layout.fragment_todo); 20 } 21 22 @Override 23 public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 24 super.onViewCreated(view, savedInstanceState); 25 26 TaskAdapter taskAdapter = new TaskAdapter(); 27 28 RecyclerView recyclerView = view.findViewById(R.id.recyclerViewTasks); 29 recyclerView.setAdapter(taskAdapter); 30 31 FragmentManager fm = getChildFragmentManager(); 32 fm.setFragmentResultListener(AddTaskFragment.REQUEST_KEY, getViewLifecycleOwner(), (rkey, result) -> { 33 taskAdapter.addTask((Task) result.getSerializable(AddTaskFragment.RESULTKEY_TASK)); 34 }); 35 36 Button btBackStudy = view.findViewById(R.id.btBackTodo); 37 btBackStudy.setOnClickListener(v -> { 38 Toast.makeText(getContext(), "戻るボタンがクリックされました", Toast.LENGTH_SHORT).show(); 39 getParentFragmentManager().setFragmentResult(REQUEST_KEY, new Bundle()); //(MainActivity に)通知 40 }); 41 42 Button addButton = view.findViewById(R.id.btAdd); 43 addButton.setOnClickListener(v -> { 44 Toast.makeText(getContext(), "追加ボタンがクリックされました", Toast.LENGTH_SHORT).show(); 45 new AddTaskFragment().show(fm, null); //ダイアログ表示 46 }); 47 } 48} 49 50class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.ViewHolder> { 51 private final List<Task> taskList = new ArrayList<>(); 52 53 void addTask(Task task) { 54 Log.d("TaskAdded", "Task added: " + task); 55 taskList.add(task); 56 notifyItemInserted(taskList.size()-1); 57 } 58 59 @NonNull 60 @Override 61 public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 62 return new ViewHolder(parent); 63 } 64 65 @Override 66 public void onBindViewHolder(@NonNull ViewHolder holder, int position) { 67 Log.d("AdapterDebug", "onBindViewHolder called for position: " + position); 68 holder.bind(taskList.get(position)); 69 } 70 71 @Override 72 public int getItemCount() { 73 return taskList.size(); 74 } 75 76 static class ViewHolder extends RecyclerView.ViewHolder { 77 private final TextView taskName, dateTime; 78 79 public ViewHolder(@NonNull ViewGroup parent) { 80 super(LayoutInflater.from(parent.getContext()).inflate(R.layout.task_item, parent, false)); 81 taskName = itemView.findViewById(R.id.taskNameTextView); 82 dateTime = itemView.findViewById(R.id.dateTimeTextView); 83 } 84 void bind(Task task) { 85 taskName.setText(task.taskName); 86 dateTime.setText(task.getDateTime()); 87 } 88 } 89} 90 91class Task implements Serializable { 92 static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm"); 93 94 final String taskName; 95 final LocalDateTime dateTime; 96 97 public Task(String taskName, LocalDateTime dateTime) { 98 this.taskName = taskName; 99 this.dateTime = dateTime; 100 } 101 String getDateTime() { 102 return formatter.format(dateTime); 103 } 104 105 @Override 106 public String toString() { 107 return taskName + " at " + getDateTime(); 108 } 109}

AddTaskFragment.java

java

1import androidx.annotation.*; 2import androidx.appcompat.app.AlertDialog; 3import androidx.fragment.app.DialogFragment; 4 5import android.app.*; 6import android.os.Bundle; 7import android.view.*; 8import android.widget.*; 9 10import java.time.*; 11 12public class AddTaskFragment extends DialogFragment { 13 static final String REQUEST_KEY = "AddTaskFragment"; 14 static final String RESULTKEY_TASK = "task"; 15 16 private EditText nameView, datetimeView; 17 private LocalDateTime datetime; 18 19 @NonNull 20 @Override 21 public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { 22 View view = LayoutInflater.from(requireContext()).inflate(R.layout.fragment_add_task, null); 23 24 datetime = LocalDateTime.now(); 25 26 nameView = view.findViewById(R.id.editTextTaskName); 27 datetimeView = view.findViewById(R.id.editTextDateTime); 28 datetimeView.setOnClickListener(v -> showDatePickerDialog()); 29 30 return new AlertDialog.Builder(requireContext()) 31 .setTitle("Add Task") 32 .setView(view) 33 .setPositiveButton("保存", (d, w) -> { 34 String name = nameView.getText().toString(); 35 Bundle result = new Bundle(); 36 result.putSerializable(RESULTKEY_TASK, new Task(name, datetime)); 37 getParentFragmentManager().setFragmentResult(REQUEST_KEY, result); 38 dismiss(); 39 }) 40 .setNegativeButton("キャンセル", (d, w) -> dismiss()) 41 .create(); 42 } 43 44 private void showDatePickerDialog() { 45 DatePickerDialog datePickerDialog = new DatePickerDialog(getContext(), (v, y, m, d) -> { //m: 0-11 46 datetime = datetime.with(LocalDate.of(y, m+1, d)); //m: 1-12 47 showTimePickerDialog(); 48 }, datetime.getYear(), datetime.getMonthValue()-1, datetime.getDayOfMonth()); //m: 0-11 49 datePickerDialog.show(); 50 } 51 52 private void showTimePickerDialog() { 53 TimePickerDialog timePickerDialog = new TimePickerDialog(getContext(), (v, h, m) -> { 54 datetime = datetime.with(LocalTime.of(h, m)); 55 datetimeView.setText(Task.formatter.format(datetime)); 56 }, datetime.getHour(), datetime.getMinute(), true); 57 timePickerDialog.show(); 58 } 59}

投稿2023/12/10 07:47

編集2023/12/10 08:14
jimbe

総合スコア12659

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ottosay

2023/12/10 10:19

1から10まで全て教えて頂きありがとうございます。 また、調べても分からないことがあれば聞きたいくらい感謝しています!!
ottosay

2023/12/10 16:11

遅くにすみません、質問をすること自体が初めてでわからないのですが、回答者の方に送っていただいたソースコードは利用してもいいのでしょうか?
jimbe

2023/12/10 17:33 編集

誰でも見られるところに書いていますので、基本的には自由に使って頂いて良いと思います。 法的な部分につきましては利用規約 https://teratail.com/legal の第9条辺りが該当すると思いますが、ホーリツは良く分かりません(*_*)
ottosay

2023/12/11 14:36

教えていただきありがとうございます!
ottosay

2023/12/11 17:25

遅くにすみません。メイン画面に戻るボタンは機能しているのですが、メイン画面に戻ってからTodoの画面に遷移すると追加したはずのタスクが消えてしまいます。。色々とコードを打ってみたのですが、うまくいきません。。。 また、追加したタスクが完了したときに簡単に削除できるように削除ボタンを作成したのですが、これもうまくいきません。。 https://maausa.marurm.com/android-listview/#index_id7 このサイトを参考にしていたのですが、うまくいきません。。 アドバイスを頂けないでしょうか。
jimbe

2023/12/11 18:37

質問を編集して別の質問にはしないでください。 teratail は、 QA の形で情報を蓄積することも目的としています。 もし ottosay さんと同様に RecyclerView の表示で困っている人が teratail に来ても、この質問にその情報があると判断出来無くなります。 同じコードや発展させたコードに対するものだとしても、他に同じ悩みを持って情報を探している人が質問を見つけて解決方法を得ることが出来るようにお考え下さい。 https://teratail.com/help/question-tips
jimbe

2023/12/11 18:50 編集

>~このサイトを参考にして~ 参考にされているサイトは ListView で SQLite を使って~という流れのようですが、 ViewModel 等はどう使うおつもりでしょうか。 (質問を再編集して元に戻され、新たに削除ボタンに関する質問を立てて頂ければそちらに移動します。)
ottosay

2023/12/12 05:15

分かりました。 もう一度説明し直したいと思います。
guest

0

Android StudioならJavaよりKotlinを使った方がいいです。

投稿2023/12/10 08:34

jmdajmw

総合スコア302

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問