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

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

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

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

Android Studio

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

Q&A

解決済

1回答

585閲覧

共有プリファレンスの値を使ってチェックボックスを作りたい

BIWD

総合スコア10

Java

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

Android Studio

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

1グッド

1クリップ

投稿2023/01/13 02:18

編集2023/01/20 01:07

前提

エディットテキストに入力した値からチェックボックスを作り、それの追加や消去を行うアプリを作っています。

実現したいこと

一度作ったチェックボックスは次回アプリ起動時にも消されずに表示されたままになるようにしたいです。

発生している問題・エラーメッセージ

共有プリファレンスに入れた値からアプリ起動時にチェックボックスを作ろうと、layout.addView(view); の一文を入れるとエラーでアプリが落ちてしまいます。

該当のソースコード

MainActivity.java

1package com.example.check2; 2import androidx.appcompat.app.AlertDialog; 3import androidx.appcompat.app.AppCompatActivity; 4 5import android.content.DialogInterface; 6import android.content.SharedPreferences; 7import android.os.Bundle; 8import android.preference.Preference; 9import android.preference.PreferenceManager; 10import android.view.View; 11import android.widget.Button; 12import android.widget.EditText; 13import android.widget.LinearLayout; 14import android.widget.TextView; 15 16public class MainActivity extends AppCompatActivity { 17 18 Button add; 19 AlertDialog dialog; 20 LinearLayout layout; 21 String s = ""; 22 String s1; 23 SharedPreferences pref; 24 SharedPreferences.Editor e; 25 26 @Override 27 protected void onCreate(Bundle savedInstanceState) { 28 super.onCreate(savedInstanceState); 29 setContentView(R.layout.activity_main); 30 31 pref = PreferenceManager.getDefaultSharedPreferences(this); 32 33 add = findViewById(R.id.add); 34 layout = findViewById(R.id.container); 35 36 buildDialog(); 37 38 add.setOnClickListener(new View.OnClickListener() { 39 @Override 40 public void onClick(View v) { 41 dialog.show(); 42 } 43 }); 44 45 //もし共有プリファレンスに値があったらそれのチェックボックスを作る処理(addCard2)へ 46 s1 = pref.getString("current",null); 47 if (s1 == null) { 48 return; 49 }else{ 50 addCard2(); 51 } 52 } 53 54 private void buildDialog() { 55 AlertDialog.Builder builder = new AlertDialog.Builder(this); 56 View view = getLayoutInflater().inflate(R.layout.dialog, null); 57 58 final EditText name = view.findViewById(R.id.nameEdit); 59 60 builder.setView(view); 61 builder.setTitle("もちものついか") 62 .setPositiveButton("ついか", new DialogInterface.OnClickListener() { 63 @Override 64 public void onClick(DialogInterface dialog, int which) { 65 addCard(name.getText().toString()); 66 name.setText(""); 67 } 68 }) 69 .setNegativeButton("やめる", new DialogInterface.OnClickListener() { 70 @Override 71 public void onClick(DialogInterface dialog, int which) { 72 name.setText(""); 73 74 } 75 }); 76 dialog = builder.create(); 77 } 78 79 private void addCard(String name) { 80 final View view = getLayoutInflater().inflate(R.layout.card, null); 81 pref = PreferenceManager.getDefaultSharedPreferences(this); 82 83 SharedPreferences.Editor e = pref.edit(); 84 85 TextView nameView = view.findViewById(R.id.name); 86 Button delete = view.findViewById(R.id.delete); 87 88 nameView.setText(name); 89 90 91// 次回起動時もチェックボックスが残る様に共有プリファレンスに名前を保存 92 s = s + name + ","; 93 e.putString("current", s); 94 e.commit(); 95 96 delete.setOnClickListener(new View.OnClickListener() { 97 @Override 98 public void onClick(View v) { 99 layout.removeView(view); 100 } 101 }); 102 layout.addView(view); 103 } 104 105 106// アプリ起動時の共有プリファレンスチェックボックス作成処理 107 private void addCard2() { 108 final View view = getLayoutInflater().inflate(R.layout.card, null); 109 pref = PreferenceManager.getDefaultSharedPreferences(this); 110 111 TextView nameView = view.findViewById(R.id.name); 112 113 s1 = pref.getString("current",null); 114 115// s1の値を","で区切って一次元配列(s2)にする 116 String[] s2 = s1.split(","); 117 118// 一次元配列 s2の内容を使ってチェックボックスを作成 119 for(int i = 0; i < s2.length; i++){ 120 nameView.setText(s2[i]);. 121//  ↓↓↓↓↓↓この1文を入れるとエラーが出てしまいます↓↓↓↓↓↓ 122 layout.addView(view); 123 } 124 } 125}

activityMain.xml

1<?xml version="1.0" encoding="utf-8"?> 2<RelativeLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:tools="http://schemas.android.com/tools" 5 xmlns:app="http://schemas.android.com/apk/res-auto" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 tools:context=".MainActivity"> 9 10 <Button 11 android:id="@+id/add" 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 android:text="✙ ついか" 15 android:layout_marginBottom="10dp" 16 android:layout_centerHorizontal="true" 17 android:layout_alignParentBottom="true"/> 18 19 20 <ScrollView 21 android:layout_width="match_parent" 22 android:layout_height="match_parent" 23 android:layout_marginBottom="70dp" 24 android:scrollbars="none"> 25 <LinearLayout 26 android:id="@+id/container" 27 android:layout_width="match_parent" 28 android:layout_height="wrap_content" 29 android:orientation="vertical"> 30 31 </LinearLayout> 32 </ScrollView> 33</RelativeLayout>

 

dialog.xml

1<?xml version="1.0" encoding="utf-8"?> 2<RelativeLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:tools="http://schemas.android.com/tools" 5 xmlns:app="http://schemas.android.com/apk/res-auto" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 tools:context=".MainActivity"> 9 10 <Button 11 android:id="@+id/add" 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 android:text="✙ ついか" 15 android:layout_marginBottom="10dp" 16 android:layout_centerHorizontal="true" 17 android:layout_alignParentBottom="true"/> 18 19 20 <ScrollView 21 android:layout_width="match_parent" 22 android:layout_height="match_parent" 23 android:layout_marginBottom="70dp" 24 android:scrollbars="none"> 25 <LinearLayout 26 android:id="@+id/container" 27 android:layout_width="match_parent" 28 android:layout_height="wrap_content" 29 android:orientation="vertical"> 30 31 </LinearLayout> 32 </ScrollView> 33</RelativeLayout>

card.xml

1<?xml version="1.0" encoding="utf-8"?> 2<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 xmlns:app="http://schemas.android.com/apk/res-auto"> 6 7 <RelativeLayout 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content" 10 > 11 12 <androidx.cardview.widget.CardView 13 android:layout_width="match_parent" 14 android:layout_height="wrap_content" 15 android:layout_margin="10dp" 16 app:cardCornerRadius="10dp" 17 app:cardElevation="10dp"> 18 19 <RelativeLayout 20 android:layout_width="match_parent" 21 android:layout_height="wrap_content" 22 android:padding="10dp"> 23 24 <CheckBox 25 android:id="@+id/name" 26 android:layout_width="wrap_content" 27 android:layout_height="wrap_content" 28 android:textColor="@android:color/holo_purple" 29 android:textFontWeight="1000" 30 android:textSize="20dp"/> 31 32 <Button 33 android:id="@+id/delete" 34 android:text="✖" 35 android:layout_width="50dp" 36 android:layout_height="50dp" 37 android:layout_alignParentEnd="true" 38 android:layout_alignParentRight="true"/> 39 </RelativeLayout> 40 </androidx.cardview.widget.CardView> 41 </RelativeLayout> 42</RelativeLayout>

試したこと

プログラムを消したり増やしたり。

補足情報(FW/ツールのバージョンなど)

Nexus6P API 28をアンドロイドスタジオ上では使用しています。

BEWD👍を押しています

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

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

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

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

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

jimbe

2023/01/13 02:46 編集

コード類(ソースコード、xml等)はファイル毎にコードのマークダウンを用いて質問本文と区切りがつくようにしてください。 ダイアログのxml のイメージも失敗しているようです。 質問は編集出来、プレビューもされているはずですので、表示を確認しながら修正してみてください。 エラーが出るのでしたら、そのエラーもご提示ください。
guest

回答1

0

ベストアンサー

コードを見ただけの状態ですが、ちょっと勘違いされているようです。

エラーが発生するという行はループ内で view を add していますが、 view はループの外で一回 inflate されているだけです。
add により view はビューの階層に組み込まれますが、それは root を根とするツリー状ですので、 1 つの view が複数回 1 つのツリー内に現れることは出来ません。(1つの view を複数のツリーに add することも出来ません。)

やろうとされていることを考えますと、自分で生成・追加等をするよりも、 普通に RecyclerView 等を使ったほうが良いのではないでしょうか。


RecyclerView 版です。

MainActivity.java

java

1import android.content.SharedPreferences; 2import android.os.Bundle; 3import android.view.*; 4import android.widget.*; 5 6import androidx.annotation.NonNull; 7import androidx.appcompat.app.*; 8import androidx.recyclerview.widget.RecyclerView; 9 10import java.util.*; 11 12public class MainActivity extends AppCompatActivity { 13 @Override 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 setContentView(R.layout.activity_main); 17 18 RecyclerView list = findViewById(R.id.list); 19 Adapter adapter = new Adapter(getPreferences(MODE_PRIVATE), "current"); 20 list.setAdapter(adapter); 21 22 Button add = findViewById(R.id.add); 23 add.setOnClickListener(v -> { 24 View view = getLayoutInflater().inflate(R.layout.dialog, null, false); 25 EditText name = view.findViewById(R.id.nameEdit); 26 new AlertDialog.Builder(MainActivity.this) 27 .setView(view) 28 .setTitle("もちものついか") 29 .setPositiveButton("ついか", (d,i) -> adapter.add(name.getText().toString())) 30 .setNegativeButton("やめる", null) 31 .create() 32 .show(); 33 }); 34 } 35 36 private static class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> { 37 private class ViewHolder extends RecyclerView.ViewHolder { 38 final CheckBox nameView; 39 public ViewHolder(@NonNull View itemView) { 40 super(itemView); 41 nameView = itemView.findViewById(R.id.name); 42 Button delete = itemView.findViewById(R.id.delete); 43 delete.setOnClickListener(v -> remove(getAdapterPosition())); 44 } 45 } 46 47 private final SharedPreferences pref; 48 private final String prefKey; 49 private final List<String> list = new ArrayList<>(); 50 51 Adapter(SharedPreferences pref, String prefKey) { 52 this.pref = pref; 53 this.prefKey = prefKey; 54 55 String value = pref.getString(prefKey, null); 56 if(value != null) { 57 for(String name : value.split(",")) list.add(name); 58 } 59 } 60 61 void add(String name) { 62 list.add(name); 63 store(); 64 notifyItemInserted(list.size() - 1); 65 } 66 67 void remove(int position) { 68 if(position < 0) return; 69 list.remove(position); 70 store(); 71 notifyItemRemoved(position); 72 } 73 74 private void store() { 75 pref.edit().putString(prefKey, getValue()).commit(); 76 } 77 78 private String getValue() { 79 if(list.isEmpty()) return null; 80 StringJoiner sj = new StringJoiner(","); 81 for(String value : list) sj.add(value); 82 return sj.toString(); 83 } 84 85 @NonNull 86 @Override 87 public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 88 return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.card, null, false)); 89 } 90 91 @Override 92 public void onBindViewHolder(@NonNull ViewHolder holder, int position) { 93 holder.nameView.setText(list.get(position)); 94 } 95 96 @Override 97 public int getItemCount() { 98 return list.size(); 99 } 100 } 101}

res/layout/activity_main.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent" 7 tools:context=".MainActivity"> 8 9 <androidx.recyclerview.widget.RecyclerView 10 android:id="@+id/list" 11 android:layout_width="match_parent" 12 android:layout_height="match_parent" 13 android:layout_marginBottom="70dp" 14 app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" 15 app:layout_constraintBottom_toTopOf="@id/add" 16 app:layout_constraintEnd_toEndOf="parent" 17 app:layout_constraintStart_toStartOf="parent" 18 app:layout_constraintTop_toTopOf="parent" /> 19 20 <Button 21 android:id="@+id/add" 22 android:layout_width="wrap_content" 23 android:layout_height="wrap_content" 24 android:layout_marginBottom="10dp" 25 android:text="✙ ついか" 26 app:layout_constraintBottom_toBottomOf="parent" 27 app:layout_constraintEnd_toEndOf="parent" 28 app:layout_constraintStart_toStartOf="parent" /> 29 30</androidx.constraintlayout.widget.ConstraintLayout>

res/layout/card.xml

xml

1<?xml version="1.0" encoding="utf-8"?> 2<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 android:layout_width="match_parent" 5 android:layout_height="wrap_content" 6 android:layout_margin="10dp" 7 app:cardCornerRadius="10dp" 8 app:cardElevation="10dp"> 9 10 <RelativeLayout 11 android:layout_width="match_parent" 12 android:layout_height="wrap_content" 13 android:padding="10dp"> 14 15 <CheckBox 16 android:id="@+id/name" 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content" 19 android:textColor="@android:color/holo_purple" 20 android:textFontWeight="1000" 21 android:textSize="20dp" /> 22 23 <Button 24 android:id="@+id/delete" 25 android:layout_width="50dp" 26 android:layout_height="50dp" 27 android:layout_alignParentEnd="true" 28 android:layout_alignParentRight="true" 29 android:text="" /> 30 31 </RelativeLayout> 32 33</androidx.cardview.widget.CardView>

投稿2023/01/13 02:53

編集2023/01/13 04:25
jimbe

総合スコア12632

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

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

BIWD

2023/01/13 05:32

丁寧な回答ありがとうございます。 いただいたプログラムを実行してみたところ、無事成功することができました! ので、ベストアンサーとさせていただきます。 RecyclerViewも知らないようなアプリ開発初心者だったので、具体的な回答がすごくありがたかったです。 本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問