今まで学んできた様々な技術を織り交ぜてtodoアプリを作ってみよう。
Q1
todoアプリを作成せよ。データをファイルに保存し、再起動した際に情報を復元できるようにすること。
必要であれば以下のアイコンをダウンロードして使用してよい。
[素材]
[実行例]
スタート画面
todoを登録するボタンがある。
ボタンを押すとSubに遷移して入力フォームが現れる
todoを入力し、アイコンを選ぶ
登録ボタンを押すと、Mainに遷移しリストビューに登録されている。
何件か登録してみる。
項目をタップするとSubに遷移し、編集ができる。この時ボタンの文言は「更新」となっていることに注意
todoとアイコンを編集し、更新ボタンを押す。
Mainに戻り、情報が更新されている。
項目を長押しすると、確認のダイアログが表示される。
はいを押すと項目が削除される(いいえでキャンセル)
●activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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="match_parent" > <Button android:id="@+id/button" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginTop="8dp" android:onClick="btAdd" android:text="todo追加" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" android:layout_marginStart="8dp" android:layout_marginEnd="8dp" /> <ListView android:id="@+id/lv" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginTop="8dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/button" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="8dp" /> </android.support.constraint.ConstraintLayout>
●activity_sub.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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="match_parent" android:padding="16dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="0dp" android:text="todo" app:layout_constraintLeft_toLeftOf="parent" android:id="@+id/textView2" app:layout_constraintBaseline_toBaselineOf="@+id/etTodo" /> <EditText android:id="@+id/etTodo" android:layout_width="0dp" android:layout_height="wrap_content" android:ems="10" android:inputType="textPersonName" android:text="" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="8dp" app:layout_constraintLeft_toRightOf="@+id/textView2" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" app:layout_constraintRight_toRightOf="parent" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="0dp" android:layout_marginTop="8dp" android:text="icon" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toBottomOf="@+id/etTodo" /> <RadioGroup android:id="@+id/rg" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginTop="8dp" android:orientation="horizontal" app:layout_constraintLeft_toRightOf="@+id/textView3" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/etTodo"> <RadioButton android:id="@+id/rb1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="赤" /> <RadioButton android:id="@+id/rb2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="緑" /> <RadioButton android:id="@+id/rb3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="青" /> </RadioGroup> <Button android:id="@+id/btBack" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_marginTop="8dp" android:onClick="btBack" android:text="登録" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/rg" /> </android.support.constraint.ConstraintLayout>
●list_item.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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" android:padding="16dp"> <ImageView android:id="@+id/iv" android:layout_width="60dp" android:layout_height="60dp" app:srcCompat="@drawable/star_b" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="0dp" android:layout_marginLeft="0dp" app:layout_constraintLeft_toLeftOf="parent" /> <TextView android:id="@+id/tvTodo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="8dp" android:padding="10dp" android:text="TextView" app:layout_constraintLeft_toRightOf="@+id/iv" tools:layout_editor_absoluteY="25dp" /> </android.support.constraint.ConstraintLayout>
●Todo.java
import java.io.Serializable; public class Todo implements Serializable { private String todo; private int resId; public Todo(String todo,int resId){ this.todo=todo; this.resId=resId; } public String getTodo(){ return this.todo; } public int getResId() { return this.resId; } public void setTodo(String todo) { this.todo=todo; } public void setResId(int resId){ this.resId=resId; } }
●TodoAdapter.java
import android.app.Activity; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import java.util.List; public class TodoAdapter extends BaseAdapter { private LayoutInflater inflater; private int layout; private List<Todo> list; public TodoAdapter(Context c,int layout,List<Todo> list){ inflater=((Activity)c).getLayoutInflater(); this.layout=layout; this.list=list; } @Override public int getCount() { return list.size(); } @Override public Todo getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Todo todo=this.getItem(position); ViewHolder holder; if(convertView == null){ convertView=inflater.inflate(this.layout,null); holder=new ViewHolder(convertView); convertView.setTag(holder); }else{ holder=(ViewHolder)convertView.getTag(); } holder.iv.setImageResource(todo.getResId()); holder.tvTodo.setText(todo.getTodo()); return convertView; } private static class ViewHolder{ TextView tvTodo; ImageView iv; public ViewHolder(View v){ tvTodo=(TextView)v.findViewById(R.id.tvTodo); iv=(ImageView)v.findViewById(R.id.iv); } } }
●MyDialog.java
import android.app.Dialog; import android.app.DialogFragment; import android.content.DialogInterface; import android.os.Bundle; import android.support.v7.app.AlertDialog; public class MyDialog extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Bundle b=this.getArguments(); final Todo todo=(Todo)b.getSerializable("todo"); AlertDialog.Builder builder=new AlertDialog.Builder(getActivity()); builder.setTitle("確認") .setMessage(todo.getTodo()+"を削除してよろしいですか?") .setPositiveButton("はい", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { MainActivity activity=(MainActivity)getActivity(); activity.removeItem(todo); } }) .setNegativeButton("いいえ", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); return builder.create(); } }
●MainActivity.java
import android.app.DialogFragment; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.Toast; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { public static final int ADD=1,UPDATE=2; private List<Todo> list=new ArrayList<>(); private TodoAdapter adapter; private ListView lv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Object ret=this.readFile(); if(ret != null){ list=(List<Todo>)ret; } lv=(ListView)findViewById(R.id.lv); adapter=new TodoAdapter(this,R.layout.list_item,list); lv.setAdapter(adapter); lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent i=new Intent(MainActivity.this,SubActivity.class); i.putExtra("requestCode",UPDATE); i.putExtra("todo",list.get(position)); i.putExtra("index",position); startActivityForResult(i,UPDATE); } }); lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { Bundle b=new Bundle(); b.putSerializable("todo",list.get(position)); DialogFragment dialog=new MyDialog(); dialog.setArguments(b); dialog.show(getFragmentManager(),"tag"); return true; } }); } public void btAdd(View v){ Intent i=new Intent(this,SubActivity.class); i.putExtra("requestCode",ADD); startActivityForResult(i,ADD); } public void removeItem(Todo todo){ list.remove(todo); adapter.notifyDataSetChanged(); Toast.makeText(this,todo.getTodo()+"を削除しました。",Toast.LENGTH_SHORT).show(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode == RESULT_OK){ Todo t=(Todo)data.getSerializableExtra("todo"); switch(requestCode){ case ADD: list.add(t); break; case UPDATE: int index=data.getIntExtra("index",-1); list.set(index,t); break; } adapter.notifyDataSetChanged(); } } @Override protected void onPause() { super.onPause(); saveFile(); } private void saveFile() { ObjectOutputStream oos=null; try { FileOutputStream fos=openFileOutput("data.dat",MODE_PRIVATE); oos=new ObjectOutputStream(fos); oos.writeObject(list); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally{ if(oos != null){ try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } } private Object readFile(){ Object ret=null; ObjectInputStream ois=null; try { FileInputStream fis=openFileInput("data.dat"); ois=new ObjectInputStream(fis); ret=ois.readObject(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if(ois != null){ try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } return ret; } }
●SubActivity.java
import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.RadioGroup; public class SubActivity extends AppCompatActivity { private EditText etTodo; private RadioGroup rg; private Button btBack; private Todo t; private int requestCode; private int index; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sub); etTodo=(EditText)findViewById(R.id.etTodo); rg=(RadioGroup)findViewById(R.id.rg); btBack=(Button)findViewById(R.id.btBack); Intent i=this.getIntent(); requestCode=i.getIntExtra("requestCode",-1); index=i.getIntExtra("index",-1); if(requestCode == MainActivity.UPDATE){ btBack.setText("更新"); t=(Todo)i.getSerializableExtra("todo"); etTodo.setText(t.getTodo()); switch(t.getResId()){ case R.drawable.star_r: rg.check(R.id.rb1); break; case R.drawable.star_g: rg.check(R.id.rb2); break; case R.drawable.star_b: rg.check(R.id.rb3); break; } } } public void btBack(View v){ Intent i=new Intent(); String todo=etTodo.getText().toString(); int resId; int checkedId=rg.getCheckedRadioButtonId(); switch(checkedId){ case R.id.rb1: resId=R.drawable.star_r; break; case R.id.rb2: resId=R.drawable.star_g; break; case R.id.rb3: resId=R.drawable.star_b; break; default: resId=R.drawable.star_r; break; } switch(this.requestCode){ case MainActivity.ADD: t=new Todo(todo,resId); break; case MainActivity.UPDATE: t.setTodo(todo); t.setResId(resId); i.putExtra("index",index); break; } i.putExtra("todo",t); this.setResult(RESULT_OK,i); this.finish(); } }
コメント