Category Archives

2 Articles
A simple way to get watch screen type from LinearLayout

A simple way to get watch screen type from LinearLayout

Recently I was trying to make some adjustments to a screen size for Android Wear so the watch would match the screen size. Most of the ways to do this always seem roundabout to me. I wanted a way to call a simple function like isRound()and get the information I need. I found a custom view someone made on the forms and modified it to return whether the screen is round or square as well.

Here is the custom view class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class WearLinearLayout extends LinearLayout {

    private int chin;
    private boolean isRound;
   
    public WearLinearLayout(Context context) {
        super(context);
    }

    public WearLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public WearLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public int getChinSize() {
        return chin;
    }

    public boolean isRound() {
        return this.isRound;
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        this.chin = insets.getSystemWindowInsetBottom();
        this.isRound = insets.isRound();

        return insets;
    }
}

It can then be implemented in the layout just like a LinearLayout.

Here is an example of how I used it to change the padding size of the bottom of the layout if the watch wasn’t round or had a chin:

1
2
3
if(!linearLayout.isRound() || linearLayout.getChinSize() > 0) {
                        int paddingBottom = getResources().getDimensionPixelSize(R.dimen.square_chin_padding_bottom);
                        controls.setPadding(0,0,0, paddingBottom);

Another Way…

Here’s a method I got from Sterling Udell on the Android Wear Developers Community.

Declare two resource values in bools.xml

1
2
3
4
5
6
7
8
9
values/bools.xml:
<resources>
    <bool name="is_round">false</bool>
</resources>

values-round/bools.xml:
<resources>
    <bool name="is_round">true</bool>
</resources>

and call getResources().getBoolean()

You can then check if the height is smaller than the width of the screen on a round screen to see if it has a chin. I made a class I use in my projects called DimenHelper to do just that:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class DimenHelper {
    public static int GetScreenWidth(Context context) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics.widthPixels;
    }

    public static int GetScreenHeight(Context context) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics.heightPixels;
    }
}

What do you think? Does this seem like an acceptable method, or is there an easier way to do this?

How to crossfade drawer layouts in wearable:2.0.5

How to crossfade drawer layouts in wearable:2.0.5

I have a wearable drawer layout in my Android app. The behavior was that the peek view would display the peek fragment and when the user swiped up, the peek fragment would fade to the content fragment.

I recently attempted to update my android wear project from wearable 2.0.3 to wearable 2.0.5. A lot of components need to be changed from wearable.view to wear.widget.

After the update, both fragments display weather the drawer is open or closed. I tried fading these in and out manually, but there didn’t seem a way to do this smoothly or easily. Is the previous behavior possible anymore?

A side note: Using a view within the activity instead of a fragment for the peek view will work as before, but remove the chevron symbol. Another workaround is to add the symbol yourself, but the animation doesn’t work as before.

Previous Drawer Layout:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<android.support.wearable.view.drawer.WearableActionDrawer
   android:id="@+id/bottom_action_drawer"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="?android:attr/colorPrimary"
   app:drawer_content="@+id/nowPlayingFragment">
    <!-- Peek View -->
    <fragment
       android:id="@+id/peekFragment"
       android:name="com.turndapage.navmusic.ui.fragment.PeekFragment"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />

    <fragment
       android:id="@+id/nowPlayingFragment"
       android:name="com.turndapage.navmusic.ui.fragment.NowPlayingFragment"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />

</android.support.wearable.view.drawer.WearableActionDrawer>

 

New Drawer Layout:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<android.support.wear.widget.drawer.WearableActionDrawerView
    android:id="@+id/bottom_action_drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:attr/colorPrimary"
    app:drawer_content="@+id/nowPlayingFragment"
    app:peekView="@+id/peek_view">


    <fragment
        android:id="@+id/nowPlayingFragment"
        android:name="com.turndapage.navmusic.ui.fragment.NowPlayingFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <!-- Peek View -->
    <fragment
        android:id="@+id/peekFragment"
        android:name="com.turndapage.navmusic.ui.fragment.PeekFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</android.support.wear.widget.drawer.WearableActionDrawerView>

 

My manual solution was this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
wearableDrawerLayout.setDrawerStateCallback(new WearableDrawerLayout.DrawerStateCallback() {

        @Override
        public void onDrawerStateChanged(WearableDrawerLayout layout, int newState) {
            super.onDrawerStateChanged(layout, newState);
            if(nowPlayingUtil != null) {
                // If the drawer is settling into position and it was opened all the way.
                if (wearableActionDrawer.getDrawerState() == WearableDrawerView.STATE_SETTLING && nowPlayingUtil != null) {
                    // Transitioning from peek view
                    if (drawerState == "drawerPeeking")
                        nowPlayingUtil.fadeToOpen();
                    // Transitioning from open view
                    else if (drawerState == "drawerOpen")
                        nowPlayingUtil.fadeToPeek();
                    else if (drawerState == "drawerClosed")
                        nowPlayingUtil.fadeToPeek();
                }
                if (wearableActionDrawer.getDrawerState() == WearableDrawerView.STATE_IDLE) {
                    // update the previous State
                    if (wearableActionDrawer.isOpened()) {
                        drawerState = "drawerOpen";
                        nowPlayingUtil.fadeToOpen();
                    } else if (wearableActionDrawer.isPeeking()) {
                        drawerState = "drawerPeeking";
                        nowPlayingUtil.fadeToPeek();
                    } else if (wearableActionDrawer.isClosed()) {
                        drawerState = "drawerClosed";
                        nowPlayingUtil.fadeToPeek();
                    }
                }
            }
        }
    });

In my example, the fadeToPeek and fadeToOpen animate the opacity of the two views to create the desired effect. Hopefully there will be a better solution in the future, but I am satisfied with this one.