avatarErnio Hernandez

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

8995

Abstract

       </div>
        </div>
    </figure></iframe></div></div></figure><p id="a958">In Jetpack Compose, the Modifier.fillMaxSize() ensures that the layout takes up the available space, adapting to different screen sizes. Additionally, using a padding modifier can provide a consistent margin, maintaining a clean and organized appearance across various dimensions.</p><p id="cc20"><b>Managing Orientations:</b></p>
    <figure id="e303">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/LethalMaus/df4d1bf10cfa95fce51b5726f625cd1a.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="864f">By checking the current orientation using LocalConfiguration.current.orientation, you can conditionally define different layouts within a Composable function.</p><h2 id="e9ba">SlidingPaneLayout for Foldables</h2><div id="af7f" class="link-block">
      <a href="https://developer.android.com/jetpack/androidx/releases/slidingpanelayout">
        <div>
          <div>
            <h2>Slidingpanelayout | Jetpack | Android Developers</h2>
            <div><h3>Implement a sliding pane UI pattern. To add a dependency on SlidingPaneLayout, you must add the Google Maven repository…</h3></div>
            <div><p>developer.android.com</p></div>
          </div>
          <div>
            <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*Mc7vQwPTUyZoP5KW)"></div>
          </div>
        </div>
      </a>
    </div><ul><li>Incorporate SlidingPaneLayout to create a sliding panel UI for foldable devices.</li></ul>
    <figure id="b2b5">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/LethalMaus/fd469a275aa7e2540f14e0eb889c47d0.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="6ee5">By leveraging these techniques in both Databinding and Jetpack Compose, you can create adaptive layouts that gracefully accommodate different screen sizes, orientations, and even the unique form factors of foldable devices. Whether adjusting dimensions or employing dynamic layouts, the goal is to provide users with a consistent and delightful experience across the diverse spectrum of devices.</p><h1 id="629e">Navigating the Pitfalls &amp; Best Practices</h1><h2 id="6483">Common Pitfalls and How to Avoid Them</h2><p id="c90b"><b>Fixed Dimensions:</b></p><ul><li><b>Pitfall:</b> Hardcoding dimensions can lead to layout distortion on different screen sizes.</li><li><b>Solution:</b> Use relative dimensions, such as wrap_content and match_parent, or utilize density-independent pixels (dp) for consistent sizing across screens.</li><li><b>XML Databinding Example:</b></li></ul>
    <figure id="4910">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/LethalMaus/97189675738255ea3f8326436851255e.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><ul><li><b>Jetpack Compose Example:</b></li></ul>
    <figure id="018c">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/LethalMaus/c6621ee3965756693058026eeb462b83.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="dc90"><b>Ignoring Density Independence:</b></p><ul><li><b>Pitfall</b>: Relying solely on fixed pixel values may lead to inconsistent UI across devices with different pixel densities.</li><li><b>Solution:</b> Use density-independent units (dp in XML, dp or sp in Compose) to ensure that UI elements scale appropriately on different screens.</li><li><b>XML DataBinding:</b></li></ul><div id="0838"><pre><span class="hljs-comment">&lt;!-- res/layout/activity_main.xml --&gt;</span>

<span class="hljs-tag"><<span class="hljs-name">TextView</span> <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span> <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span> <span class="hljs-attr">android:textSize</span>=<span class="hljs-string">"16sp"</span> <span class="hljs-attr">android:padding</span>=<span class="hljs-string">"8dp"</span> <span class="hljs-attr">android:text</span>=<span class="hljs-string">"Density-independent Text"</span> /></span></pre></div><ul><li><b>Jetpack Compose:</b></li></ul><div id="24b2"><pre>/<span class="hljs-regexp">/ src/main</span><span class="hljs-regexp">/kotlin/com</span><span class="hljs-regexp">/example/myapp</span><span class="hljs-regexp">/ui/</span><span class="hljs-title class_">MainScreen</span>.kt <span class="hljs-title class_">Text</span>( text = <span class="hljs-string">"Density-independent Text"</span>, fontSize = <span class="hljs-number">16</span>.sp, modifier = <span class="hljs-title class_">Modifier</span>.padding(<span class="hljs-number">8</span>.dp) )</pre></div><p id="c31d"><b>Ignoring Orientation Changes:</b></p><ul><li><b>Pitfall: </b>Neglecting landscape or portrait orientations may result in suboptimal user experiences.</li><li><b>Solution:</b> Design landscape-specific layouts for improved usability when the device is rotated.</li><li><b>XML Databinding Example:</b></li></ul><div id="6536"><pre><span class="hljs-comment"><!-- res/layout-land/activity_main.xml --></span> <span class="hljs-tag"><<span class="hljs-name">LinearLayout</span> <span class="hljs-attr">android:orientation</span>=<span class="hljs-string">"horizontal"</span> <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span> <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"match_parent"</span>></span> <span class="hljs-comment"><!-- Landscape-specific UI components --></span> <span class="hljs-tag"></<span class="hljs-name">LinearLayout</span>></span></pre></div><ul><li><b>Jetpack Compose Example:</b></li></ul> <figure id="fcde"> <div> <div>

            <iframe class="gist-iframe" src="/gist/LethalMaus/c34e8858c7bf0d4ae15671d14f67b382.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="913c"><b>Neglecting Foldable Device Considerations:</b></p><ul><li><b>Pitfall:</b> Overlooking the unique form factor of foldable devices may lead to suboptimal user experiences.</li><li><b>Solution:</b> Incorporate resource qualifiers for foldable devices and tailor layouts to make the most of their capabilities.</li><li><b>XML Databinding Example:</b></li></ul><div id="f275"><pre><span class="hljs-comment">&lt;!-- res/layout-large/activity_main.xml --&gt;</span>

<span class="hljs-tag"><<span class="hljs-name">LinearLayout</span> <span class="hljs-attr">android:orientation</span>=<span class="hljs-string">"vertical"</span> <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span> <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"match_parent"</span>></span> <span class="hljs-comment"><!-- Foldable device UI components --></span> <span class="hljs-tag"></<span class="hljs-name">LinearLayout</span>></span></pre></div><ul><li><b>Jetpack Compose Example:</b></li></ul> <figure id="6e49"> <div> <div>

            <iframe class="gist-iframe" src="/gist/LethalMaus/e3e1b19d494c32cae17f4908f2605805.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><h1 id="3fee">Extra Tricks for a Seamless Experience</h1><p id="0308"><b>Dynamic Spacing:</b></p><ul><li>Dynamically adjust spacing based on screen size using dimension resources.</li><li><b>XML Databinding Example:</b></li></ul><div id="1ddf"><pre><span class="hljs-tag">&lt;<span class="hljs-name">TextView</span>
<span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span>
<span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>
<span class="hljs-attr">android:text</span>=<span class="hljs-string">"Dynamic Spacing"</span>
<span class="hljs-attr">android:layout_margin</span>=<span class="hljs-string">"@dimen/margin_standard"</span> /

Options

></span></pre></div><ul><li><b>Jetpack Compose Example:</b></li></ul><div id="a566"><pre><span class="hljs-selector-tag">Text</span>( text = <span class="hljs-string">"Dynamic Spacing"</span>, modifier = Modifier .<span class="hljs-built_in">padding</span>(<span class="hljs-built_in">dimensionResource</span>(id = R.dimen.margin_standard)) )</pre></div><p id="1ec8"><b>Responsive Font Sizes:</b></p><ul><li>Use dimension resources to adjust font sizes responsively.</li><li><b>XML Databinding Example:</b></li></ul><div id="7238"><pre><span class="hljs-tag"><<span class="hljs-name">TextView</span> <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"wrap_content"</span> <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span> <span class="hljs-attr">android:text</span>=<span class="hljs-string">"Responsive Font"</span> <span class="hljs-attr">android:textSize</span>=<span class="hljs-string">"@dimen/text_size_medium"</span> /></span></pre></div><ul><li><b>Jetpack Compose Example:</b></li></ul><div id="879d"><pre><span class="hljs-keyword">Text</span>( <span class="hljs-keyword">text</span> = <span class="hljs-string">"Responsive Font"</span>, fontSize = dimensionResource(id = R.dimen.text_size_medium).value )</pre></div><p id="ff03">Navigating the diverse landscape of screen sizes, orientations, and foldable devices requires attention to detail. By avoiding common pitfalls and implementing these extra tricks, you can create adaptive layouts that provide a seamless and enjoyable user experience across a wide range of devices.</p><h1 id="724b">Testing Across the Spectrum: Espresso, Firebase Device Farm, and Emulators</h1><p id="f7de">Ensuring your app performs seamlessly across diverse screen sizes and orientations requires a robust testing strategy. In this section, we’ll explore how to effectively test your application using Espresso, leverage Firebase Device Farm for comprehensive device coverage, and set up custom emulators tailored to your testing needs. Additionally, we’ll provide scripts for running these tests, both locally and within a continuous integration (CI) pipeline.</p><h2 id="d5d7">Espresso for Local Testing</h2><p id="3c72">Espresso is a powerful testing framework for Android that allows you to write concise and reliable UI tests. To test different screen sizes and orientations locally, you can use Espresso’s ViewMatchers and ViewActions in conjunction with the ViewAssertions to validate UI elements.</p><p id="1119"><b>Espresso Code Example:</b></p> <figure id="e57e"> <div> <div>

            <iframe class="gist-iframe" src="/gist/LethalMaus/d59c45ea83a143f9e81cabff1e5294b2.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><h2 id="ade1">Firebase Device Farm for Comprehensive Testing</h2><div id="c926" class="link-block">
      <a href="https://firebase.google.com/docs/test-lab">
        <div>
          <div>
            <h2>Firebase Test Lab</h2>
            <div><h3>Test your app on devices hosted in a Google data center.</h3></div>
            <div><p>firebase.google.com</p></div>
          </div>
          <div>
            <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/0*_syWJhiB1iPapT92)"></div>
          </div>
        </div>
      </a>
    </div><p id="624c">Firebase Device Farm provides a cloud-based solution for testing your app on a wide range of real devices. You can create test matrices to cover different screen sizes, orientations, and devices, ensuring thorough testing across various configurations.</p>
    <figure id="f3c7">
        <div>
          <div>
            <img class="ratio" src="http://placehold.it/16x9">
            <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F4_ZEEX1x17k%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D4_ZEEX1x17k&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F4_ZEEX1x17k%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" allowfullscreen="" frameborder="0" height="480" width="854">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="e689"><b>Firebase Test Lab Code Example:</b></p>
    <figure id="83a5">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/LethalMaus/f4f1bc1cb5b2e0e9acd015c4b88d7697.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><h2 id="3b50">Emulator Setup for Custom Testing Environments</h2><p id="9c86">Android emulators provide a flexible way to create custom virtual devices for testing. You can configure emulators to match specific screen sizes, resolutions, and orientations to mimic real-world scenarios.</p><h2 id="d185">Custom Emulator Setup:</h2><p id="6b87"><b>Create a new emulator with AVD Manager: </b>Specify device details such as screen size, resolution, and orientation.</p><div id="cc39"><pre>emulator -avd <span class="hljs-title class_">Pixel</span>_6_API_32 -orientation portrait</pre></div><p id="2825"><b>Start the emulator:</b> Launch the emulator with the desired configuration.</p><h2 id="b314">Script for Running Tests Locally:</h2><div id="b14f"><pre><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Assuming your Espresso tests are in the 'androidTest' directory</span> ./gradlew connectedAndroidTest</pre></div><h2 id="8c3b">Script for CI Pipeline (Firebase Device Farm Integration):</h2> <figure id="411f"> <div> <div>

            <iframe class="gist-iframe" src="/gist/LethalMaus/f42ef9d5be37616ab0d3f7c4fe74245e.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="2828">By incorporating these testing strategies into your development workflow, you can ensure that your app functions seamlessly across a spectrum of screen sizes, resolutions, and orientations. Whether testing locally with Espresso, exploring diverse configurations on Firebase Device Farm, or creating custom emulators, a comprehensive testing approach is essential for delivering a high-quality user experience.</p><h1 id="1d6d">Conclusion</h1><p id="123e">It is more important than ever to design experiences that work seamlessly across a wide range of screen sizes, orientations, and foldable devices. This exploration of the nuances of multi-form factor testing and development has made the way clearer for developers trying to figure out how to deal with the challenges of the digital world.</p><p id="7a08">Using the ideas of adaptable design in both Jetpack Compose and XML databinding, developers can create layouts that fluidly adjust to the ever-widening range of devices. The adaptability provided by these methods guarantees that customers, irrespective of the device they use, get a consistent and enjoyable experience on smartphones, tablets, and foldables.</p><p id="8650">Testing, a cornerstone of app development, has been explored through the lenses of Espresso, Firebase Device Farm, and emulator setups. From local testing to cloud-based solutions, developers can employ a variety of tools to ensure their apps perform flawlessly across diverse environments. Whether running Espresso tests for specific configurations, leveraging Firebase for comprehensive device coverage, or scripting emulator setups for local and CI/CD pipeline testing, the arsenal is rich with options.</p><p id="bdba">As we approach to the end of this investigation, it is clear that embracing diversity is essential for success. By grasping the subtleties of various form factors, avoiding typical mistakes, and adding extra tactics, developers can make applications that are capable of surpassing constraints. In a world where creativity has no boundaries, progressive developers continue to be distinguished by their commitment to creating inclusive and flexible digital experiences.</p><p id="7b0b">I hope that this article acts as a compass for developers, helping them navigate the complexities of developing and testing multi-screen applications and providing inspiration for the construction of programmes that not only fulfil current needs but also remain robust in the face of future technological breakthroughs. We look forward to a time when consumers everywhere will be able to explore a universe of seamless possibilities with each tap, swipe, and fold.</p></article></body>

I Got Mugged for My 18th Birthday

Let me start by admitting I brought this whole ordeal upon myself with one very stupid question.

original photo by Dakota Corbin

Knowing that this benchmark birthday was coming, and maybe trying to head off my anxiety (fear) that I’d have no one to celebrate this “big life event” with, I booked myself a flight and hotel room to New Orleans. Yup, myself.

A solo journey. Maybe partly an act of rebellious independence. I was used to being alone, so why not travel alone? Maybe I would meet someone new? Or someone kinda new.

At the time I was “involved” with a woman who I met in a chatroom. As one can imagine, those curvy quotes around the word involved suggest something far more than friendly conversation. (Albeit just online.) She had confessed to me once that she was married IRL. So there was always the chance of her husband discovering this. Which only fed into the taboo appeal of it all the more.

I was young (dumb). I scoffed off her dalliance to nothing more than idle curiosity. I was merely the cyber equivalent of a warm body. I could type nice things to her about the female form and I had time to pay attention to her. And really, it was “just online.”

But then maybe it could go offline. I don’t remember where she lived, but I remember thinking the possibility of a New Orleans rendezvous with her was not completely out of the realm of chance. In one of our chats, she offered to get me a discount on my hotel since she worked for a chain. The discount never happened, there was a hotel mixup and I had already settled in and liked my proximity to The French Quarter, so I stayed put and paid little mind to the extra cost. The chance meetup never happened either, but I paid little mind to not seeing her; IRL wrongdoing averted.

Off to take in the town solo, mostly to take in its food into my belly, I hit the ATM to get some cash and then enjoyed a lunch at Lucky Cheng’s. (Why I frequented a drag queen nightclub in the middle of the day I will never know, but I made far stranger choices on this trip.)

The weather seemed nice enough to walk around Bourbon Street and see what the Louisiana afternoon had to offer me. Apparently, what it had to offer was drugs. No, check that, it provided me with what amounted to a suggestion of drug use. “You got any papers?,” a local denizen had asked me as we crossed paths.

Here is where that very stupid question, that far stranger choice and maybe a smidge of social awkwardness all come back into play. Instead of simply shaking my head in the negative and walking by this obviously-not-looking-for-idle-conversation gentleman, I decide to engage.

Let me also add one small preface to this story before I divulge my foot-in-mouth verbal spew: I was not only JUST turning 18, I also had never drank, smoked, had sex or any kind of drugs in those entire 18 years. So you may be as baffled as I was to hear these words that came out of my young, clean-shaven face:

“No. Do you know where I can get some?”

All I had to do was stop at my one-word utterance! “No.” Perfect response. And I would have gone on to enjoy the rest of my NOLA days in sweet, innocent peace. But no, the new independent Ernio had to continue with the stupidest, strangest, most non-sensical, 8-word question to ever leave his body.

My one-man audience seemed to take this in stride. Obviously a complete stranger, a young tourist he’d never met before, would make a great companion for his journey to paper enlightenment. He agreed to help me acquire some of our “shared” pasttime and I… walked aimlessly beside him.

What was my plan? How far would I follow this guy before I kindly… remembered something else… I had to do? Would I simply renege on my desire? Was I going to purchase him some of his wanted “papers” in return for the favor? What in the fuck was I thinking?

We walked up Bourbon and turned down a sidestreet, my sherpa chatting me up with charming Southern small talk. We were headed out of The French Quarter and I had yet to come up with anything resembling an exit strategy. Surely, there was a beignet at Café du Monde with my name on it, no? Come on, Ernio! Well, I guess a trip to where real locals frequent would be fine. Right?!

We crossed Rampart into definitively non-tourist territory and my guide had me wait at a corner while he got me “hooked up” with who-even-knows-what? It would be rude of me to simply leave at this point, no? [SMH, facepalm, etc.] So he returned to the corner and said his friend told him there was a guy just up the block.

I followed him. (Sure!???) I followed him into an abandoned house. (What could possibly go wrong!?) I followed him through an abandoned house into a backyard where — wouldn’t you know it?—there was no “guy.” Just the friend he had talked to moments ago.

At this point, my curbside acquaintance begins to playact being worried that his friend is going to shoot me. (Nono, don’t fret.) Worried that his friend is going to shoot me through the front pocket of his jacket (really, no worries). Shoot me through his jacket pocket with what is obviously his finger in the shape of a gun.

Is this really happening to me?

Now (oh NOW?!!) clearly seeing no way out of this, I give over all my cash and show them the wallet where there is nothing left. My scene partner reveals that he took me for some kind of cop attempting to entrap him. That’s why he walked me by the police station to see if any of my fellow boys in blue would recognize me. I assured him and the lone fingerman I was just from out of town here on vacation. As a gesture of good faith, I even emptied out my pockets of all the change I had gathered in my days there. “That’s all I have.”

Luckily, I made it out of there with nothing bruised but my ego. I headed back through The French Quarter with my tail between my legs and returned to my hotel room without further incident. I showered and napped, trying to reset the day.

That night, I entered into adulthood slightly wiser. My wild, teenaged recklessness rolled up into one trip somewhat behind me. I ordered a shrimp po’boy from room service and stayed in watching TV until I fell asleep. Happy birthday me.

Short Story
Nonfiction
This Happened To Me
Life Lessons
Life
Recommended from ReadMedium