今まで学んできた様々な技術を織り交ぜてtodoアプリを作ってみよう。
Q1
todoアプリを作成せよ。データをファイルに保存し、再起動した際に情報を復元できるようにすること。
必要であれば以下のアイコンをダウンロードして使用してよい。
[素材]



[実行例]
スタート画面
todoを登録するボタンがある。

ボタンを押すとSubに遷移して入力フォームが現れる

todoを入力し、アイコンを選ぶ

登録ボタンを押すと、Mainに遷移しリストビューに登録されている。

何件か登録してみる。

項目をタップするとSubに遷移し、編集ができる。この時ボタンの文言は「更新」となっていることに注意

todoとアイコンを編集し、更新ボタンを押す。

Mainに戻り、情報が更新されている。

項目を長押しすると、確認のダイアログが表示される。

はいを押すと項目が削除される(いいえでキャンセル)

●activity_main.xml
01 | <? xml version = "1.0" encoding = "utf-8" ?> |
02 | < android.support.constraint.ConstraintLayout xmlns:android = "http://schemas.android.com/apk/res/android" |
03 | xmlns:app = "http://schemas.android.com/apk/res-auto" |
04 | android:layout_width = "match_parent" |
05 | android:layout_height = "match_parent" |
09 | android:id = "@+id/button" |
10 | android:layout_width = "0dp" |
11 | android:layout_height = "wrap_content" |
12 | android:layout_marginLeft = "8dp" |
13 | android:layout_marginRight = "8dp" |
14 | android:layout_marginTop = "8dp" |
15 | android:onClick = "btAdd" |
17 | app:layout_constraintLeft_toLeftOf = "parent" |
18 | app:layout_constraintRight_toRightOf = "parent" |
19 | app:layout_constraintTop_toTopOf = "parent" |
20 | android:layout_marginStart = "8dp" |
21 | android:layout_marginEnd = "8dp" /> |
25 | android:layout_width = "0dp" |
26 | android:layout_height = "0dp" |
27 | android:layout_marginLeft = "8dp" |
28 | android:layout_marginRight = "8dp" |
29 | android:layout_marginTop = "8dp" |
30 | app:layout_constraintLeft_toLeftOf = "parent" |
31 | app:layout_constraintRight_toRightOf = "parent" |
32 | app:layout_constraintTop_toBottomOf = "@+id/button" |
33 | app:layout_constraintBottom_toBottomOf = "parent" |
34 | android:layout_marginBottom = "8dp" /> |
35 | </ android.support.constraint.ConstraintLayout > |
●activity_sub.xml
01 | <? xml version = "1.0" encoding = "utf-8" ?> |
02 | < android.support.constraint.ConstraintLayout xmlns:android = "http://schemas.android.com/apk/res/android" |
03 | xmlns:app = "http://schemas.android.com/apk/res-auto" |
04 | android:layout_width = "match_parent" |
05 | android:layout_height = "match_parent" |
06 | android:padding = "16dp" |
10 | android:layout_width = "wrap_content" |
11 | android:layout_height = "wrap_content" |
12 | android:layout_marginLeft = "0dp" |
14 | app:layout_constraintLeft_toLeftOf = "parent" |
15 | android:id = "@+id/textView2" |
16 | app:layout_constraintBaseline_toBaselineOf = "@+id/etTodo" /> |
19 | android:id = "@+id/etTodo" |
20 | android:layout_width = "0dp" |
21 | android:layout_height = "wrap_content" |
23 | android:inputType = "textPersonName" |
25 | app:layout_constraintTop_toTopOf = "parent" |
26 | android:layout_marginTop = "8dp" |
27 | app:layout_constraintLeft_toRightOf = "@+id/textView2" |
28 | android:layout_marginLeft = "8dp" |
29 | android:layout_marginRight = "8dp" |
30 | app:layout_constraintRight_toRightOf = "parent" /> |
33 | android:id = "@+id/textView3" |
34 | android:layout_width = "wrap_content" |
35 | android:layout_height = "wrap_content" |
36 | android:layout_marginLeft = "0dp" |
37 | android:layout_marginTop = "8dp" |
39 | app:layout_constraintLeft_toLeftOf = "parent" |
40 | app:layout_constraintTop_toBottomOf = "@+id/etTodo" /> |
44 | android:layout_width = "0dp" |
45 | android:layout_height = "wrap_content" |
46 | android:layout_marginLeft = "8dp" |
47 | android:layout_marginRight = "8dp" |
48 | android:layout_marginTop = "8dp" |
49 | android:orientation = "horizontal" |
50 | app:layout_constraintLeft_toRightOf = "@+id/textView3" |
51 | app:layout_constraintRight_toRightOf = "parent" |
52 | app:layout_constraintTop_toBottomOf = "@+id/etTodo" > |
56 | android:layout_width = "wrap_content" |
57 | android:layout_height = "wrap_content" |
58 | android:layout_weight = "1" |
63 | android:layout_width = "wrap_content" |
64 | android:layout_height = "wrap_content" |
65 | android:layout_weight = "1" |
70 | android:layout_width = "wrap_content" |
71 | android:layout_height = "wrap_content" |
72 | android:layout_weight = "1" |
77 | android:id = "@+id/btBack" |
78 | android:layout_width = "0dp" |
79 | android:layout_height = "wrap_content" |
80 | android:layout_marginLeft = "8dp" |
81 | android:layout_marginRight = "8dp" |
82 | android:layout_marginTop = "8dp" |
83 | android:onClick = "btBack" |
85 | app:layout_constraintLeft_toLeftOf = "parent" |
86 | app:layout_constraintRight_toRightOf = "parent" |
87 | app:layout_constraintTop_toBottomOf = "@+id/rg" /> |
88 | </ android.support.constraint.ConstraintLayout > |
●list_item.xml
01 | <? xml version = "1.0" encoding = "utf-8" ?> |
02 | < android.support.constraint.ConstraintLayout xmlns:android = "http://schemas.android.com/apk/res/android" |
03 | xmlns:app = "http://schemas.android.com/apk/res-auto" |
04 | xmlns:tools = "http://schemas.android.com/tools" |
05 | android:layout_width = "match_parent" |
06 | android:layout_height = "match_parent" |
07 | android:padding = "16dp" > |
11 | android:layout_width = "60dp" |
12 | android:layout_height = "60dp" |
13 | app:srcCompat = "@drawable/star_b" |
14 | app:layout_constraintTop_toTopOf = "parent" |
15 | android:layout_marginTop = "0dp" |
16 | android:layout_marginLeft = "0dp" |
17 | app:layout_constraintLeft_toLeftOf = "parent" /> |
20 | android:id = "@+id/tvTodo" |
21 | android:layout_width = "wrap_content" |
22 | android:layout_height = "wrap_content" |
23 | android:layout_marginLeft = "8dp" |
24 | android:padding = "10dp" |
25 | android:text = "TextView" |
26 | app:layout_constraintLeft_toRightOf = "@+id/iv" |
27 | tools:layout_editor_absoluteY = "25dp" /> |
28 | </ android.support.constraint.ConstraintLayout > |
●Todo.java
01 | import java.io.Serializable; |
03 | public class Todo implements Serializable { |
06 | public Todo(String todo, int resId){ |
10 | public String getTodo(){ |
14 | public int getResId() { |
18 | public void setTodo(String todo) { |
21 | public void setResId( int resId){ |
●TodoAdapter.java
01 | import android.app.Activity; |
02 | import android.content.Context; |
03 | import android.view.LayoutInflater; |
04 | import android.view.View; |
05 | import android.view.ViewGroup; |
06 | import android.widget.BaseAdapter; |
07 | import android.widget.ImageView; |
08 | import android.widget.TextView; |
12 | public class TodoAdapter extends BaseAdapter { |
13 | private LayoutInflater inflater; |
15 | private List<Todo> list; |
16 | public TodoAdapter(Context c, int layout,List<Todo> list){ |
17 | inflater=((Activity)c).getLayoutInflater(); |
23 | public int getCount() { |
28 | public Todo getItem( int position) { |
29 | return list.get(position); |
33 | public long getItemId( int position) { |
38 | public View getView( int position, View convertView, ViewGroup parent) { |
39 | Todo todo= this .getItem(position); |
41 | if (convertView == null ){ |
42 | convertView=inflater.inflate( this .layout, null ); |
43 | holder= new ViewHolder(convertView); |
44 | convertView.setTag(holder); |
46 | holder=(ViewHolder)convertView.getTag(); |
48 | holder.iv.setImageResource(todo.getResId()); |
49 | holder.tvTodo.setText(todo.getTodo()); |
52 | private static class ViewHolder{ |
55 | public ViewHolder(View v){ |
56 | tvTodo=(TextView)v.findViewById(R.id.tvTodo); |
57 | iv=(ImageView)v.findViewById(R.id.iv); |
●MyDialog.java
01 | import android.app.Dialog; |
02 | import android.app.DialogFragment; |
03 | import android.content.DialogInterface; |
04 | import android.os.Bundle; |
05 | import android.support.v7.app.AlertDialog; |
07 | public class MyDialog extends DialogFragment { |
09 | public Dialog onCreateDialog(Bundle savedInstanceState) { |
10 | Bundle b= this .getArguments(); |
11 | final Todo todo=(Todo)b.getSerializable( "todo" ); |
12 | AlertDialog.Builder builder= new AlertDialog.Builder(getActivity()); |
13 | builder.setTitle( "確認" ) |
14 | .setMessage(todo.getTodo()+ "を削除してよろしいですか?" ) |
15 | .setPositiveButton( "はい" , new DialogInterface.OnClickListener() { |
17 | public void onClick(DialogInterface dialog, int which) { |
18 | MainActivity activity=(MainActivity)getActivity(); |
19 | activity.removeItem(todo); |
22 | .setNegativeButton( "いいえ" , new DialogInterface.OnClickListener() { |
24 | public void onClick(DialogInterface dialog, int which) { |
28 | return builder.create(); |
●MainActivity.java
001 | import android.app.DialogFragment; |
002 | import android.content.Intent; |
003 | import android.os.Bundle; |
004 | import android.support.v7.app.AppCompatActivity; |
005 | import android.view.View; |
006 | import android.widget.AdapterView; |
007 | import android.widget.ListView; |
008 | import android.widget.Toast; |
010 | import java.io.FileInputStream; |
011 | import java.io.FileNotFoundException; |
012 | import java.io.FileOutputStream; |
013 | import java.io.IOException; |
014 | import java.io.ObjectInputStream; |
015 | import java.io.ObjectOutputStream; |
016 | import java.util.ArrayList; |
017 | import java.util.List; |
019 | public class MainActivity extends AppCompatActivity { |
020 | public static final int ADD= 1 ,UPDATE= 2 ; |
021 | private List<Todo> list= new ArrayList<>(); |
022 | private TodoAdapter adapter; |
026 | protected void onCreate(Bundle savedInstanceState) { |
027 | super .onCreate(savedInstanceState); |
028 | setContentView(R.layout.activity_main); |
029 | Object ret= this .readFile(); |
031 | list=(List<Todo>)ret; |
033 | lv=(ListView)findViewById(R.id.lv); |
034 | adapter= new TodoAdapter( this ,R.layout.list_item,list); |
035 | lv.setAdapter(adapter); |
036 | lv.setOnItemClickListener( new AdapterView.OnItemClickListener() { |
038 | public void onItemClick(AdapterView<?> parent, View view, int position, long id) { |
039 | Intent i= new Intent(MainActivity. this ,SubActivity. class ); |
040 | i.putExtra( "requestCode" ,UPDATE); |
041 | i.putExtra( "todo" ,list.get(position)); |
042 | i.putExtra( "index" ,position); |
043 | startActivityForResult(i,UPDATE); |
046 | lv.setOnItemLongClickListener( new AdapterView.OnItemLongClickListener() { |
048 | public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { |
049 | Bundle b= new Bundle(); |
050 | b.putSerializable( "todo" ,list.get(position)); |
051 | DialogFragment dialog= new MyDialog(); |
052 | dialog.setArguments(b); |
053 | dialog.show(getFragmentManager(), "tag" ); |
058 | public void btAdd(View v){ |
059 | Intent i= new Intent( this ,SubActivity. class ); |
060 | i.putExtra( "requestCode" ,ADD); |
061 | startActivityForResult(i,ADD); |
063 | public void removeItem(Todo todo){ |
065 | adapter.notifyDataSetChanged(); |
066 | Toast.makeText( this ,todo.getTodo()+ "を削除しました。" ,Toast.LENGTH_SHORT).show(); |
070 | protected void onActivityResult( int requestCode, int resultCode, Intent data) { |
071 | super .onActivityResult(requestCode, resultCode, data); |
072 | if (resultCode == RESULT_OK){ |
073 | Todo t=(Todo)data.getSerializableExtra( "todo" ); |
079 | int index=data.getIntExtra( "index" ,- 1 ); |
083 | adapter.notifyDataSetChanged(); |
088 | protected void onPause() { |
093 | private void saveFile() { |
094 | ObjectOutputStream oos= null ; |
096 | FileOutputStream fos=openFileOutput( "data.dat" ,MODE_PRIVATE); |
097 | oos= new ObjectOutputStream(fos); |
098 | oos.writeObject(list); |
100 | } catch (FileNotFoundException e) { |
102 | } catch (IOException e) { |
108 | } catch (IOException e) { |
114 | private Object readFile(){ |
116 | ObjectInputStream ois= null ; |
118 | FileInputStream fis=openFileInput( "data.dat" ); |
119 | ois= new ObjectInputStream(fis); |
120 | ret=ois.readObject(); |
121 | } catch (FileNotFoundException e) { |
123 | } catch (IOException e) { |
125 | } catch (ClassNotFoundException e) { |
131 | } catch (IOException e) { |
●SubActivity.java
01 | import android.content.Intent; |
02 | import android.os.Bundle; |
03 | import android.support.v7.app.AppCompatActivity; |
04 | import android.view.View; |
05 | import android.widget.Button; |
06 | import android.widget.EditText; |
07 | import android.widget.RadioGroup; |
09 | public class SubActivity extends AppCompatActivity { |
10 | private EditText etTodo; |
11 | private RadioGroup rg; |
12 | private Button btBack; |
14 | private int requestCode; |
17 | protected void onCreate(Bundle savedInstanceState) { |
18 | super .onCreate(savedInstanceState); |
19 | setContentView(R.layout.activity_sub); |
20 | etTodo=(EditText)findViewById(R.id.etTodo); |
21 | rg=(RadioGroup)findViewById(R.id.rg); |
22 | btBack=(Button)findViewById(R.id.btBack); |
23 | Intent i= this .getIntent(); |
24 | requestCode=i.getIntExtra( "requestCode" ,- 1 ); |
25 | index=i.getIntExtra( "index" ,- 1 ); |
26 | if (requestCode == MainActivity.UPDATE){ |
28 | t=(Todo)i.getSerializableExtra( "todo" ); |
29 | etTodo.setText(t.getTodo()); |
31 | case R.drawable.star_r: |
34 | case R.drawable.star_g: |
37 | case R.drawable.star_b: |
45 | public void btBack(View v){ |
46 | Intent i= new Intent(); |
47 | String todo=etTodo.getText().toString(); |
49 | int checkedId=rg.getCheckedRadioButtonId(); |
52 | resId=R.drawable.star_r; |
55 | resId=R.drawable.star_g; |
58 | resId=R.drawable.star_b; |
61 | resId=R.drawable.star_r; |
64 | switch ( this .requestCode){ |
66 | case MainActivity.ADD: |
67 | t= new Todo(todo,resId); |
69 | case MainActivity.UPDATE: |
72 | i.putExtra( "index" ,index); |
78 | this .setResult(RESULT_OK,i); |
コメント