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

WearSquare: Introduction to Android Wear Desig...

WearSquare: Introduction to Android Wear Design & Development

David Vávra

January 06, 2015
Tweet

More Decks by David Vávra

Other Decks in Technology

Transcript

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

    follow 1/5 Wearable UI Library DelayedConfirmationView
  2. 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
  3. 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
  4. 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
  5. 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
  6. Do one thing, really fast 4/5 Display most important data

    + action buttons CircledImageView ActionFragment
  7. 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
  8. 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
  9. 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/...
  10. 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
  11. 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