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

Avatar for David Vávra

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