Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Bingo hands-on

Bingo hands-on

Yuki Anzai

May 26, 2019
Tweet

More Decks by Yuki Anzai

Other Decks in Technology

Transcript

  1. Yuki Anzai • Android App Developer (2009~) • CEO of

    uPhyca Inc. (2011~) • Google Developer Expert for Android • Organizer of GTUG Girls and droid girls • Twitter : @yanzm
  2. <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.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" tools:context=".MainActivity">

    <TextView android:id="@+id/historyView" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="16dp" android:layout_marginTop="16dp" android:layout_marginRight="16dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" tools:text="1, 2, 3, 4, 5" /> <Button android:id="@+id/button" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginEnd="16dp" android:layout_marginBottom="16dp" android:text="@string/next_number" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> <TextView android:id="@+id/numberView" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:layout_marginBottom="16dp" android:gravity="center" android:textSize="100sp" app:layout_constraintBottom_toTopOf="@+id/button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/historyView" tools:text="75" /> </androidx.constraintlayout.widget.ConstraintLayout>
  3. public class MainActivity extends AppCompatActivity { private TextView historyView; private

    TextView numberView; private View button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); historyView = findViewById(R.id.historyView); numberView = findViewById(R.id.numberView); button = findViewById(R.id.button); } }
  4. public class MainActivity extends AppCompatActivity { private TextView historyView; private

    TextView numberView; private View button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); historyView = findViewById(R.id.historyView); numberView = findViewById(R.id.numberView); button = findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { numberView.setText("" + System.currentTimeMillis()); } }); }
  5. public class MainActivity extends AppCompatActivity { private TextView historyView; private

    TextView numberView; private View button; private final Random random = new Random(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final int nextNumber = random.nextInt(75) + 1; numberView.setText("" + nextNumber); } });
  6. public class MainActivity extends AppCompatActivity { ... private final List<Integer>

    histories = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { ... button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final int nextNumber = random.nextInt(75); numberView.setText("" + nextNumber); histories.add(nextNumber); historyView.setText(createHistoryText()); } }); }
  7. public class MainActivity extends AppCompatActivity { ... private String createHistoryText()

    { final StringBuilder sb = new StringBuilder(); boolean isFirst = true; for (int history : histories) { if (isFirst) { isFirst = false; } else { sb.append(", "); } sb.append(history); } return sb.toString(); } }
  8. public class MainActivity extends AppCompatActivity { ... private final List<Integer>

    pickNumbers = new ArrayList<>(); private final List<Integer> histories = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); pickNumbers.clear(); for (int i = 1; i <= 75; i++) { pickNumbers.add(i); } historyView = findViewById(R.id.historyView); numberView = findViewById(R.id.numberView); button = findViewById(R.id.button);
  9. public class MainActivity extends AppCompatActivity { ... @Override protected void

    onCreate(Bundle savedInstanceState) { ... button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final int index = random.nextInt(pickNumbers.size()); final int nextNumber = pickNumbers.remove(index); numberView.setText("" + nextNumber); histories.add(nextNumber); historyView.setText(createHistoryText()); if (pickNumbers.isEmpty()) { button.setEnabled(false); } }
  10. https://developer.android.com/jetpack/androidx/releases/lifecycle dependencies { ... def lifecycle_version = "2.0.0" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"

    annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" } build.gradle (Module: app) Android developer ページ → Jetpack → AndroidX → Release Notes → androidx.lifecycle
  11. public class MainViewModel extends ViewModel { private final Random random

    = new Random(); private final List<Integer> pickNumbers = new ArrayList<>(); private final List<Integer> histories = new ArrayList<>(); public MainViewModel() { for (int i = 1; i <= 75; i++) { pickNumbers.add(i); } } int pickNextNumber() { final int index = random.nextInt(pickNumbers.size()); final int nextNumber = pickNumbers.remove(index); histories.add(nextNumber); return nextNumber; }
  12. String createHistoryText() { final StringBuilder sb = new StringBuilder(); boolean

    isFirst = true; for (int history : histories) { if (isFirst) { isFirst = false; } else { sb.append(", "); } sb.append(history); } return sb.toString(); } boolean isAllPicked() { return pickNumbers.isEmpty(); } }
  13. public class MainActivity extends AppCompatActivity { private TextView historyView; private

    TextView numberView; private View button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); historyView = findViewById(R.id.historyView); numberView = findViewById(R.id.numberView); button = findViewById(R.id.button); final MainViewModel viewModel = ViewModelProviders.of(this) .get(MainViewModel.class);
  14. public class MainActivity extends AppCompatActivity { ... @Override protected void

    onCreate(Bundle savedInstanceState) { ... button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final int nextNumber = viewModel.pickNextNumber(); numberView.setText("" + nextNumber); historyView.setText(viewModel.createHistoryText()); if (viewModel.isAllPicked()) { button.setEnabled(false); } } }); }
  15. public class MainViewModel extends ViewModel { private final Random random

    = new Random(); private final List<Integer> pickNumbers = new ArrayList<>(); private final List<Integer> histories = new ArrayList<>(); private final MutableLiveData<State> state = new MutableLiveData<>(); public MainViewModel() { pickNumbers.clear(); for (int i = 1; i <= 75; i++) { pickNumbers.add(i); } } LiveData<State> getState() { return state; }
  16. void pickNextNumber() { final int index = random.nextInt(pickNumbers.size()); final int

    nextNumber = pickNumbers.remove(index); histories.add(nextNumber); state.setValue(new State(nextNumber, createHistoryText(), isAllPicked())) } private String createHistoryText() { final StringBuilder sb = new StringBuilder(); boolean isFirst = true; for (int history : histories) { if (isFirst) { isFirst = false; } else { sb.append(", "); } sb.append(history); } return sb.toString(); }
  17. private boolean isAllPicked() { return pickNumbers.isEmpty(); } static class State

    { final int nextNumber; final String historyText; final boolean isAllPicked; State(int nextNumber, String historyText, boolean isAllPicked) { this.nextNumber = nextNumber; this.historyText = historyText; this.isAllPicked = isAllPicked; } } }
  18. public class MainActivity extends AppCompatActivity { ... @Override protected void

    onCreate(Bundle savedInstanceState) { ... viewModel.getState().observe(this, new Observer<MainViewModel.State>() { @Override public void onChanged(MainViewModel.State state) { numberView.setText("" + state.nextNumber); historyView.setText(state.historyText); if (state.isAllPicked) { button.setEnabled(false); } } });
  19. public class MainActivity extends AppCompatActivity { ... @Override protected void

    onCreate(Bundle savedInstanceState) { ... button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { viewModel.pickNextNumber(); } }); } }