WearSquare: Introduction to Android Wear Design & Development

WearSquare: Introduction to Android Wear Design & Development

Fe087c5a0e898cd95c67973aa97f2067?s=128

David Vávra

January 06, 2015
Tweet

Transcript

  1. WearSquare Introduction to Android Wear Design & Development David Vávra

  2. None
  3. None
  4. None
  5. None
  6. Design principles and how to implement them in native code

  7. Focus on not stopping the user and all else will

    follow 1/5 Wearable UI Library DelayedConfirmationView
  8. DelayedConfirmationView <android.support.wearable.view.DelayedConfirmationView android:id="@+id/confirmation" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/ic_cancel" app:circle_color="@color/action_button" app:circle_radius="40dp" app:circle_radius_pressed="35dp"

    app:circle_padding="5dp" app:circle_border_width="5dp" app:circle_border_color="@color/primary_light"/> /wear/src/main/res/layout/fragment_check_in.xml vConfirmation.setTotalTimeMs(3000); vConfirmation.start(); mTimerInvalid = false; vConfirmation.setListener(new DelayedConfirmationView. DelayedConfirmationListener() { @Override public void onTimerFinished(View view) { if (!mTimerInvalid) { ((CheckInActivity)getActivity()).sendCheckInMessage(); } } @Override public void onTimerSelected(View view) { mTimerInvalid = true; getActivity().finish(); } }); /wear/src/main/java/cz/destil/wearsquare/fragment/CheckInFragment.java
  9. Design for big gestures 2/5 3 items on screen WearableListView

  10. WearableListView <android.support.wearable.view.WearableListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="match_parent"/> /wear/src/main/res/layout/activity_fragment_list.xml public class CheckInListAdapter extends

    WearableListView.Adapter { public CheckInListAdapter(Context context, List<Venue> items){} @Override public WearableListView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {} @Override public void onBindViewHolder(WearableListView.ViewHolder viewHolder, int position) {} @Override public int getItemCount() {} class ListItem extends FrameLayout implements WearableListView. OnCenterProximityListener { @Override public void onCenterPosition(boolean b) {} @Override public void onNonCenterPosition(boolean b) {} } } /wear/src/main/java/cz/destil/wearsquare/adapter/CheckInListAdapter.java
  11. Think about stream cards first 3/5 It would be best

    to show card automatically But Don’t be a constant shoulder tapper GridViewPager FragmentGridPagerAdapter CardFragment
  12. FragmentGridPagerAdapter <FrameLayout xmlns:android="http://schemas.android. com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.wearable.view.GridViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent"

    android:background="@color/black" android:keepScreenOn="true"/> <android.support.wearable.view.DotsPageIndicator android:id="@+id/page_indicator" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal|bottom"/> </FrameLayout> /wear/src/main/res/layout/activity_gridpager.xml public class ExploreAdapter extends FragmentGridPagerAdapter { public ExploreAdapter(ExploreActivity activity, List<ExploreAdapter.Venue> items) {} @Override public Fragment getFragment(int row, int col) { final Venue venue = mItems.get(row); CardFragment fragment = CardFragment.create(venue. name, venue.tip); } @Override public Drawable getBackgroundForRow(int row) {} @Override public int getRowCount() {return mItems.size();} @Override public int getColumnCount(int rowNum) {} } /wear/src/main/java/cz/destil/wearsquare/adapter/ExploreAdapter.java
  13. Do one thing, really fast 4/5 Display most important data

    + action buttons CircledImageView ActionFragment
  14. ActionFragment <?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.wearable.view.CircledImageView android:id="@+id/icon" android:layout_width="wrap_content"

    android:layout_height="wrap_content" android:layout_centerInParent="true" app:circle_color="@color/action_button" app:circle_radius="45dp" app:circle_border_width="0dp"/> <TextView .../> </RelativeLayout> /wear/src/main/res/layout/fragment_action.xml public class ActionFragment extends BaseFragment implements View.OnClickListener { public static ActionFragment create(int iconResId, int labelResId, Listener listener) {} @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); vIcon.setImageResource(getArguments().getInt("ICON")); vLabel.setText(getArguments().getInt("LABEL")); view.setOnClickListener(this); } @Override public void onClick(View v) { mListener.onActionPerformed();} public interface Listener { public void onActionPerformed(); } } /wear/src/main/java/cz/destil/wearsquare/fragment/ActionFragment.java
  15. Design for the corner of the eye 5/5 ConfirmationActivity: ◦

    success ◦ failure ◦ open on phone
  16. ConfirmationActivity Intent i = new Intent(this, ConfirmationActivity.class); i.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.SUCCESS_ANIMATION); i.putExtra(ConfirmationActivity.EXTRA_MESSAGE,

    getString(R.string.checked_in)); startActivityForResult(i, CheckInActivity.CONFIRM_ACTIVITY); /wear/src/main/java/cz/destil/wearsquare/activity/CheckInActivity.java
  17. Q&A Code: https://github.com/destil/wearsquare App: https://play.google.com/store/apps/details?id=cz.destil.wearsquare

  18. Development tips

  19. Use Teleport library 1/3 Removes boilerplate code from Data Layer

    API https://github.com/Mariuxtheone/Teleport by GDE Mario Viviani mTeleportClient.syncString("hello", "Hello, World!"); /mobile/... mTeleportClient.setOnSyncDataItemTask(new ShowToastHelloWorldTask()); public class ShowToastHelloWorldTask extends TeleportClient.OnSyncDataItemTask { @Override protected void onPostExecute(DataMap dataMap) { String hello = dataMap.getString("hello"); Toast.makeText(context, hello, Toast.LENGTH_SHORT).show(); } } /wear/...
  20. Sync images later 2/3 private void downloadImages(Set<String> imageUrls) { int

    i = 0; mTargets = new SparseArray<>(); for (final String imageUrl : imageUrls) { mTargets.put(i, new Target() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { Asset asset = ImageUtils.createAssetFromBitmap(bitmap); final PutDataMapRequest data = PutDataMapRequest.createWithAutoAppendedId("/image"); data.getDataMap().putString("image_url", imageUrl); data.getDataMap().putAsset("asset", asset); syncDataItem(data); } @Override public void onBitmapFailed(Drawable errorDrawable) {} }); Picasso.with(App.get()).load(imageUrl).into(mTargets.get(i)); i++; } } /mobile/src/main/java/cz/destil/wearsquare/service/FoursquareService.java
  21. Send unhandled Exceptions to phone 3/3 public class App extends

    Application { @Override public void onCreate() { super.onCreate(); Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(Thread.getDefaultUncaughtExceptionHandler())); } } /wear/src/main/java/cz/destil/wearsquare/core/App.java public class ExceptionHandler implements Thread.UncaughtExceptionHandler { public ExceptionHandler(Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler) { } @Override public void uncaughtException(Thread thread, Throwable ex) { App.bus().post(new ExceptionEvent(ex)); mDefaultUncaughtExceptionHandler.uncaughtException(thread, ex); } public static void sendExceptionToPhone(Throwable exception, TeleportClient mTeleportClient) { mTeleportClient.sendMessage(buildMessageText(exception), null); } } /wear/src/main/java/cz/destil/wearsquare/util/ExceptionHandler.java