<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: katz</title>
    <description>The latest articles on Forem by katz (@kaleidot725).</description>
    <link>https://forem.com/kaleidot725</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F447011%2Fdd62e572-1a7b-4c56-88e0-7cb77039a37c.jpeg</url>
      <title>Forem: katz</title>
      <link>https://forem.com/kaleidot725</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kaleidot725"/>
    <language>en</language>
    <item>
      <title>Release Android Mirroring Tool ScrcpyHub v2.0.0</title>
      <dc:creator>katz</dc:creator>
      <pubDate>Sun, 26 Mar 2023 12:16:18 +0000</pubDate>
      <link>https://forem.com/kaleidot725/release-android-mirroring-tool-scrcpyhub-v200-2a68</link>
      <guid>https://forem.com/kaleidot725/release-android-mirroring-tool-scrcpyhub-v200-2a68</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article has been automatically translated from Japanese to English using ChatGPT.&lt;br&gt;
&lt;a href="https://qiita.com/kaleidot725/items/3c7cf8d01729f1c1b2a8"&gt;https://qiita.com/kaleidot725/items/3c7cf8d01729f1c1b2a8&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;ScrcpyHub is a GUI application for mirroring Android screens. ScrcpyHub is actively being developed at the following GitHub repository, so please feel free to contribute and star the project:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kaleidot725/ScrcpyHub"&gt;https://github.com/kaleidot725/ScrcpyHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ScrcpyHub is built using the scrcpy command tool:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Genymobile/scrcpy"&gt;https://github.com/Genymobile/scrcpy&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;ScrcpyHub supports the following features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic detection of connected Android devices&lt;/li&gt;
&lt;li&gt;Starting and stopping Android device mirroring&lt;/li&gt;
&lt;li&gt;Recording Android device screens&lt;/li&gt;
&lt;li&gt;Capturing Android device screenshots&lt;/li&gt;
&lt;li&gt;Compatibility with Windows 10/11, macOS, and Linux&lt;/li&gt;
&lt;li&gt;Switching between light and dark themes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NEW v2.0.0&lt;/strong&gt; Audio option support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NEW v2.0.0&lt;/strong&gt; Device option support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NEW v2.0.0&lt;/strong&gt; HID keyboard and mouse option support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With ScrcpyHub, you can control Android device mirroring like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xILW-tzn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/75175a2b-29e6-cc69-53ad-7fffaeafcddf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xILW-tzn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/75175a2b-29e6-cc69-53ad-7fffaeafcddf.gif" alt="demo.gif" width="480" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;NEW v2.0.0&lt;/strong&gt; Audio Option Support
&lt;/h3&gt;

&lt;p&gt;Starting from scrcpy v2.0.0, audio mirroring is possible on Android 11 and above. Therefore, ScrcpyHub v2.0.0 now supports the following audio options:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;No Audio&lt;/td&gt;
&lt;td&gt;Disable audio mirroring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bitrate(Kbps)&lt;/td&gt;
&lt;td&gt;Specify the bitrate for audio mirroring&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Buffering(ms)&lt;/td&gt;
&lt;td&gt;Specify the buffering time for audio mirroring&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2fGntqIX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/5c66b8d0-666a-5910-cc0c-9395ee4e2f2e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2fGntqIX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/5c66b8d0-666a-5910-cc0c-9395ee4e2f2e.png" alt="image.png" width="350" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;NEW v2.0.0&lt;/strong&gt; Device Option Support
&lt;/h3&gt;

&lt;p&gt;ScrcpyHub did not support scrcpy's device-related options. Starting from v2.0.0, ScrcpyHub now supports the following scrcpy device options:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Stay Awake&lt;/td&gt;
&lt;td&gt;Prevent the Android device from entering sleep mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Show touches&lt;/td&gt;
&lt;td&gt;Display touch locations on the Android device&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enable power off on stop&lt;/td&gt;
&lt;td&gt;Turn off the device when mirroring stops&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disable power on on start&lt;/td&gt;
&lt;td&gt;Prevent the device from turning on when mirroring starts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iRfITmjD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/bf8fc47b-5744-3727-7dd5-b485b8bc26cb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iRfITmjD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/bf8fc47b-5744-3727-7dd5-b485b8bc26cb.png" alt="image.png" width="350" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;NEW v2.0.0&lt;/strong&gt; HID Keyboard and Mouse Options Now Supported
&lt;/h3&gt;

&lt;p&gt;In ScrcpyHub, HID options for scrcpy were not available. As of v2.0.0, the following HID options for scrcpy are now supported:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Keyboard Simulation&lt;/td&gt;
&lt;td&gt;Start the simulation as if a keyboard is connected to the Android device&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mouse Simulation&lt;/td&gt;
&lt;td&gt;Start the simulation as if a mouse is connected to the Android device&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GBknMy7y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/75a3c1ba-7dac-aa9b-a248-7f9697c250da.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GBknMy7y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79387/75a3c1ba-7dac-aa9b-a248-7f9697c250da.png" alt="image.png" width="350" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation Instructions
&lt;/h2&gt;

&lt;p&gt;To use ScrcpyHub, you need to install adb and scrcpy commands. The installation steps vary depending on the OS, so please follow the instructions below for your specific system.&lt;/p&gt;

&lt;h3&gt;
  
  
  💻Windows 10/11
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Download and install scrcpy(v2.0.0+) from &lt;a href="https://github.com/Genymobile/scrcpy#windows"&gt;GitHub&lt;/a&gt; to any location&lt;/li&gt;
&lt;li&gt;Install and launch ScrcpyHub from &lt;a href="https://github.com/kaleidot725/ScrcpyHub/releases/tag/v2.0.0"&gt;GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Open ScrcpyHub Preferences&lt;/li&gt;
&lt;li&gt;Set the paths for adb and scrcpy, and press Save&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  💻MacOS
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Install android-platform-tools and scrcpy(v2.0.0+) using the brew command&lt;/li&gt;
&lt;li&gt;Install and launch ScrcpyHub from &lt;a href="https://github.com/kaleidot725/ScrcpyHub/releases/tag/v2.0.0"&gt;GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Open ScrcpyHub Preferences&lt;/li&gt;
&lt;li&gt;Set the paths for adb and scrcpy, and press Save
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;otherCopy code
brew install android-platform-tools
brew install scrcpy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Contact
&lt;/h2&gt;

&lt;p&gt;ScrcpyHub is actively being developed in the repository below. If you have any suggestions for improvements or encounter any issues, please feel free to contact us.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kaleidot725/ScrcpyHub"&gt;https://github.com/kaleidot725/ScrcpyHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>tooling</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Start creating simple text editor library for Jetpack Compose</title>
      <dc:creator>katz</dc:creator>
      <pubDate>Mon, 27 Jun 2022 01:19:54 +0000</pubDate>
      <link>https://forem.com/kaleidot725/start-creating-simple-text-editor-library-for-jetpack-compose-45jh</link>
      <guid>https://forem.com/kaleidot725/start-creating-simple-text-editor-library-for-jetpack-compose-45jh</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I usually use a Craft, and Craft’s text editor has a great writing feel and I have no complaints, so I thought I want a Craft-like text editor for Jetpack Compose.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.craft.do/" rel="noopener noreferrer"&gt;Craft - The Future of Documents&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2F74C503F3-9536-495C-8F8E-C988902B8896_2%2FJwbbND1m0riShiE9hfijbqKBFHKBWLHJVkFi3PJFAZ0z%2FRPReplay_Final1656133235.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2F74C503F3-9536-495C-8F8E-C988902B8896_2%2FJwbbND1m0riShiE9hfijbqKBFHKBWLHJVkFi3PJFAZ0z%2FRPReplay_Final1656133235.gif" alt="RPReplay_Final1656133235.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;so I started creating a library called text-editor-compose.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kaleidot725/text-editor-compose" rel="noopener noreferrer"&gt;GitHub - kaleidot725/text-editor-compose: A simple text editor library for Jetpack Compose&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;text-editor-compose has features as below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Edit text
&lt;/h3&gt;

&lt;p&gt;Edit the text on each line, add and delete text as follows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2FC8BCCC3C-773C-40E3-9229-53703A5AEBA7_2%2FyRlzYxke1Lfx3avcYV5r1f4sS41kuCX7nWiTrgxKhWoz%2FEMULATOR-2022_06_25_14_57_28.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2FC8BCCC3C-773C-40E3-9229-53703A5AEBA7_2%2FyRlzYxke1Lfx3avcYV5r1f4sS41kuCX7nWiTrgxKhWoz%2FEMULATOR-2022_06_25_14_57_28.gif" alt="EMULATOR-2022_06_25_14_57_28.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Line break
&lt;/h3&gt;

&lt;p&gt;Insert line breaks or delete line breaks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2FF349AD9E-027B-4D25-9198-E2CBEC4DFA82_2%2FnLYfMwkKuiMHJPJytc38LRgsH12vobVJ9VTMsgbq0bwz%2FAnimatedImage.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2FF349AD9E-027B-4D25-9198-E2CBEC4DFA82_2%2FnLYfMwkKuiMHJPJytc38LRgsH12vobVJ9VTMsgbq0bwz%2FAnimatedImage.gif" alt="AnimatedImage.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Line number
&lt;/h2&gt;

&lt;p&gt;Display line numbers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2F09E29C34-B18C-45C0-8350-9A4DD9BC7E55_2%2FavOnWTuxMzyxQU8euaBKidr4ZSUvIOQ5E8TDO5xVJWwz%2FAnimatedImage.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2F09E29C34-B18C-45C0-8350-9A4DD9BC7E55_2%2FavOnWTuxMzyxQU8euaBKidr4ZSUvIOQ5E8TDO5xVJWwz%2FAnimatedImage.gif" alt="AnimatedImage.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Selected line
&lt;/h3&gt;

&lt;p&gt;Display the selected line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2FACDFF973-CB61-4D4D-91A9-4601E26C34F9_2%2FoYx33KTx18CMUuMdS2ZbKwPKv5yZ42aaMqopDr3b0rkz%2FAnimatedImage.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2FACDFF973-CB61-4D4D-91A9-4601E26C34F9_2%2FoYx33KTx18CMUuMdS2ZbKwPKv5yZ42aaMqopDr3b0rkz%2FAnimatedImage.gif" alt="AnimatedImage.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Roadmap
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Multiple line selection
&lt;/h3&gt;

&lt;p&gt;Copy and delete are not supported for multiple lines. So I’m planning to add a multiple line selection&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2FD70F5BB8-45EF-4DFE-A9E6-796C5BFE6B87_2%2Fx7vZq0SiGdpMidpGSzoZFt68Qco1LWRJzaf74flyijwz%2FAnimatedImage.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2FD70F5BB8-45EF-4DFE-A9E6-796C5BFE6B87_2%2Fx7vZq0SiGdpMidpGSzoZFt68Qco1LWRJzaf74flyijwz%2FAnimatedImage.gif" alt="AnimatedImage.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Physical Keyboard
&lt;/h3&gt;

&lt;p&gt;Physical keyboard is not supported. So I’m planning to add physical keyboard support.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2F4308C599-3FC2-4E4D-BF99-6D544AE33382_2%2FDVN4y9jxRRDdjhHE1yixqV2t7xGEALgf5dzqQ7M7rokz%2FAnimatedImage.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FA7FDFD47-B4B7-46EE-B4B2-628642C17B3F%2F4308C599-3FC2-4E4D-BF99-6D544AE33382_2%2FDVN4y9jxRRDdjhHE1yixqV2t7xGEALgf5dzqQ7M7rokz%2FAnimatedImage.gif" alt="AnimatedImage.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;This library is easy to use, just follow the steps below to add a dependency and write codes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Add the JitPack repository to build.gradle
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;allprojects&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;repositories&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="n"&gt;maven&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="s1"&gt;'https://jitpack.io'&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Add the library to the dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'com.github.kaleidot725:text-editor-compose:0.1.0'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Declare TextEditor &amp;amp; TextEditorState
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainActivity&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ComponentActivity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bundle&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;setContent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;SampleTheme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;textEditorState&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;rememberTextEditorState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DemoText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                &lt;span class="nc"&gt;TextEditor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="n"&gt;textEditorState&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;textEditorState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                    &lt;span class="n"&gt;onUpdatedState&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;              
                    &lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillMaxSize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Customize what each row displays
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainActivity&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ComponentActivity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bundle&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;setContent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;SampleTheme&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;textEditorState&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;rememberTextEditorState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DemoText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                &lt;span class="nc"&gt;TextEditor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="n"&gt;textEditorState&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;textEditorState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;onUpdatedState&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillMaxSize&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                    &lt;span class="n"&gt;decorationBox&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;isSelected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;innerTextField&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
                        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;backgroundColor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isSelected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0x8000ff00&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;White&lt;/span&gt;           
&lt;span class="err"&gt;　　　　　　　　　　　　　　&lt;/span&gt; &lt;span class="nc"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;background&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                            &lt;span class="nc"&gt;Spacer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;width&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                            &lt;span class="nf"&gt;innerTextField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillMaxWidth&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;text-eiditor-compose has implemented minimum features. I’m planning to add new features.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kaleidot725/text-editor-compose" rel="noopener noreferrer"&gt;GitHub - kaleidot725/text-editor-compose: A simple text editor library for Jetpack Compose&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>jetpackcompose</category>
      <category>kotlin</category>
      <category>library</category>
    </item>
    <item>
      <title>Android Mirroring Tool : Release ScrcpyHub v1.6.0</title>
      <dc:creator>katz</dc:creator>
      <pubDate>Sat, 19 Mar 2022 01:44:14 +0000</pubDate>
      <link>https://forem.com/kaleidot725/android-mirroring-tool-release-scrcpyhub-v160-547i</link>
      <guid>https://forem.com/kaleidot725/android-mirroring-tool-release-scrcpyhub-v160-547i</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;ScrcpyHub is a GUI application to mirror android screen. ScrcpyHub use &lt;a href="https://github.com/Genymobile/scrcpy"&gt;scrcpy&lt;/a&gt;. &lt;a href="https://github.com/Genymobile/scrcpy"&gt;scrcpy&lt;/a&gt; is a mirroring android command tool.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kaleidot725/ScrcpyHub"&gt;https://github.com/kaleidot725/ScrcpyHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;ScrcpyHub assists in multiple device mirroring. ScrcpyHub makes it easy to do multiple device mirroring.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support Windows10/11 or macOS or Linux.&lt;/li&gt;
&lt;li&gt;Support light theme and dark theme. 🖼️&lt;/li&gt;
&lt;li&gt;Control mirroing (Start / Stop). 🪞&lt;/li&gt;
&lt;li&gt;Mirror multi android device. 📱&lt;/li&gt;
&lt;li&gt;Save Screenshot. 📸&lt;/li&gt;
&lt;li&gt;Record Movie. 🎥&lt;/li&gt;
&lt;li&gt;Support Tary Menu. 📥&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;v1.6.0 New Feature : Support max fps option.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;v1.6.0 New Feature  : Support bitrate option.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nMVG4m6_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.craft.do/user/full/3a21bd0e-fe7a-39aa-73ad-b52ef24b655b/doc/6B81409B-F369-40D8-A18F-C3EB0794AE95/0198F212-64C1-4528-9DEC-A72EBEED8992_2/LcAfFELCjRs9vCPv2FArMLyGYoeIT37oGJxeO9yi1LMz/demo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nMVG4m6_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.craft.do/user/full/3a21bd0e-fe7a-39aa-73ad-b52ef24b655b/doc/6B81409B-F369-40D8-A18F-C3EB0794AE95/0198F212-64C1-4528-9DEC-A72EBEED8992_2/LcAfFELCjRs9vCPv2FArMLyGYoeIT37oGJxeO9yi1LMz/demo.gif" alt="demo.gif" width="880" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  v1.6.0 New Feature : Support max fps and bitrate option
&lt;/h2&gt;

&lt;p&gt;Support max fps and birate option. You can change movie quality to modify max fps and bitrate option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.craft.do/user/full/3a21bd0e-fe7a-39aa-73ad-b52ef24b655b/doc/A9897ACF-0658-42B1-8C21-405BA782502F/AC8A8951-7F95-443F-B8C8-981E51FA8F78_2/h3KnUQcya6g2gkn6x9UfudNkHTLRQ06xMvKt5uKstXwz/v1.6.0.mp4"&gt;v1.6.0.mp4&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;

&lt;p&gt;Install adb and scrcpy, ScrcpyHub.&lt;/p&gt;

&lt;h4&gt;
  
  
  💻 Windows 10 / 11
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Download &lt;a href="https://github.com/Genymobile/scrcpy#windows"&gt;here&lt;/a&gt; and install scrcpy somewhere.&lt;/li&gt;
&lt;li&gt;Download &lt;a href="https://github.com/kaleidot725/scrcpy-hub/releases/tag/v1.6.0"&gt;here&lt;/a&gt; and launch ScrcpyHub.&lt;/li&gt;
&lt;li&gt;Open ScrcpyHub Preferences.&lt;/li&gt;
&lt;li&gt;Input adb and scrcpy location, save settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  💻 Linux(Ubuntu)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Download &lt;a href="https://github.com/Genymobile/scrcpy#windows"&gt;here&lt;/a&gt; and install scrcpy somewhere.&lt;/li&gt;
&lt;li&gt;Download &lt;a href="https://github.com/kaleidot725/scrcpy-hub/releases/tag/v1.6.0"&gt;here&lt;/a&gt; and install ScrcpHub.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo dpkg -i scrcpyhub_1.5.0_amd64.deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Launch ScrcpyHub, open Preferences.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/opt/scrcpyhub/bin/ScrcpyHub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Input adb and scrcpy location, save settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  💻 Mac OS
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Install android-platform-tools and scrcpy.&lt;/li&gt;
&lt;li&gt;Download &lt;a href="https://github.com/kaleidot725/scrcpy-hub/releases/tag/v1.6.0"&gt;here&lt;/a&gt; and launch ScrcpyHub.&lt;/li&gt;
&lt;li&gt;Open ScrcpyHub Preferences.&lt;/li&gt;
&lt;li&gt;Input adb and scrcpy location, save settings.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install android-platform-tools
brew install scrcpy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔥Contact
&lt;/h2&gt;

&lt;p&gt;We are working on the development &lt;a href="https://github.com/kaleidot725/ScrcpyHub"&gt;here&lt;/a&gt;.  If you have any suggestions for improvement, please contact us.&lt;/p&gt;

</description>
      <category>android</category>
      <category>mirroring</category>
      <category>app</category>
      <category>jetpackcompose</category>
    </item>
    <item>
      <title>Implementing Jetpack Compose + Orbit MVI</title>
      <dc:creator>katz</dc:creator>
      <pubDate>Thu, 10 Feb 2022 18:07:29 +0000</pubDate>
      <link>https://forem.com/kaleidot725/implementaing-jetpack-compose-orbit-mvi-3gea</link>
      <guid>https://forem.com/kaleidot725/implementaing-jetpack-compose-orbit-mvi-3gea</guid>
      <description>&lt;p&gt;I created a Pokémon Libary application with Jetpack Compose + Orbit MVI. Orbit MVI is easy to use, try it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FF6345393-103D-49B0-9A99-865E3AFA5868%2FBD2499F1-A7A3-4E37-96FF-97F6D53ECC27_2%2FyTIJGlQS4Dc52wQx4yfuAacPpIzaFV8JrB1ERKLRfzsz%2FImage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FF6345393-103D-49B0-9A99-865E3AFA5868%2FBD2499F1-A7A3-4E37-96FF-97F6D53ECC27_2%2FyTIJGlQS4Dc52wQx4yfuAacPpIzaFV8JrB1ERKLRfzsz%2FImage.png" alt="Image.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Link
&lt;/h1&gt;

&lt;p&gt;This Sample Source Code&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/kaleidot725/PokemonLibraryWithJetpackCompose" rel="noopener noreferrer"&gt;https://github.com/kaleidot725/PokemonLibraryWithJetpackCompose&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;About Jetpack Compose&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/jetpack/compose" rel="noopener noreferrer"&gt;https://developer.android.com/jetpack/compose&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;About Orbit MVI&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://orbit-mvi.org" rel="noopener noreferrer"&gt;https://orbit-mvi.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Feature
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Manage Pokémon data.&lt;/li&gt;
&lt;li&gt;Display multiple Pokémon in a list.&lt;/li&gt;
&lt;li&gt;Display a Pokémon details.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Architecture
&lt;/h1&gt;

&lt;p&gt;This application architecture is based on the MVVM + Repository pattern. But the view state management use MVI, because introduced Jetpack Compose and Orbit MVI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FF6345393-103D-49B0-9A99-865E3AFA5868%2F8AD1BC53-4EB5-416F-91C3-095BF50160F9_2%2FQhd8zDcHO337yOkh1Jq8mDJOiZK6k7ZMzmNrAAxzEjYz%2Farchitecture-OVERALL.drawio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FF6345393-103D-49B0-9A99-865E3AFA5868%2F8AD1BC53-4EB5-416F-91C3-095BF50160F9_2%2FQhd8zDcHO337yOkh1Jq8mDJOiZK6k7ZMzmNrAAxzEjYz%2Farchitecture-OVERALL.drawio.png" alt="architecture-OVERALL.drawio.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Module
&lt;/h1&gt;

&lt;p&gt;This application consists of a multi-module structure. There are three modules, and each module plays the role described in the figure below.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Content&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;App&lt;/td&gt;
&lt;td&gt;Store View and ViewModel to manage view state.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Domain&lt;/td&gt;
&lt;td&gt;Store UseCase to process business logic.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data&lt;/td&gt;
&lt;td&gt;Store Repository and Dao to manage Pokémon database.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Library
&lt;/h1&gt;

&lt;p&gt;This application is created by the  library in the bottom figures.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Name&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Link&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Koin&lt;/td&gt;
&lt;td&gt;&lt;a href="https://insert-koin.io/" rel="noopener noreferrer"&gt;https://insert-koin.io&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jetpack Compose&lt;/td&gt;
&lt;td&gt;&lt;a href="https://developer.android.com/jetpack/compose" rel="noopener noreferrer"&gt;https://developer.android.com/jetpack/compose&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Navigation Compose&lt;/td&gt;
&lt;td&gt;&lt;a href="https://developer.android.com/jetpack/compose/navigation" rel="noopener noreferrer"&gt;https://developer.android.com/jetpack/compose/navigation&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Orbit MVI&lt;/td&gt;
&lt;td&gt;&lt;a href="https://orbit-mvi.org/" rel="noopener noreferrer"&gt;https://orbit-mvi.org&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coil&lt;/td&gt;
&lt;td&gt;&lt;a href="https://coil-kt.github.io/coil/" rel="noopener noreferrer"&gt;https://coil-kt.github.io/coil/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Room&lt;/td&gt;
&lt;td&gt;&lt;a href="https://developer.android.com/training/data-storage/room?hl=ja" rel="noopener noreferrer"&gt;https://developer.android.com/training/data-storage/room?hl=ja&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kotlin-Serialiazation&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Kotlin/kotlinx.serialization" rel="noopener noreferrer"&gt;https://github.com/Kotlin/kotlinx.serialization&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PokemonGO-Pokedex&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/Biuni/PokemonGO-Pokedex" rel="noopener noreferrer"&gt;https://github.com/Biuni/PokemonGO-Pokedex&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Data Flow for UI (UI State Managment)
&lt;/h1&gt;

&lt;p&gt;This application data flow is undirectional,  as shown in the bottom figures.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;MVI View sends Action(intent) to MVI Model.&lt;/li&gt;
&lt;li&gt;MVI Model executes UseCase when received Action&lt;/li&gt;
&lt;li&gt;UseCase accesses to Repository to get Pokémon Data.&lt;/li&gt;
&lt;li&gt;UseCase returns  Pokémon Data to MVI Model.&lt;/li&gt;
&lt;li&gt;MVI Model creates new state from Pokémon Data.&lt;/li&gt;
&lt;li&gt;MVI Model sends created new states or new events to MVI View.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FF6345393-103D-49B0-9A99-865E3AFA5868%2FC46C8974-BE1B-4C0C-B4D5-E2C29F62D5DC_2%2Ft4SQ2YUUDuU3SE13IGo1MagaA9eT9SqkIT0IxSSjdpMz%2Farchitecture-DATAFLOW.drawio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2FF6345393-103D-49B0-9A99-865E3AFA5868%2FC46C8974-BE1B-4C0C-B4D5-E2C29F62D5DC_2%2Ft4SQ2YUUDuU3SE13IGo1MagaA9eT9SqkIT0IxSSjdpMz%2Farchitecture-DATAFLOW.drawio.png" alt="architecture-DATAFLOW.drawio.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This application data flow is implmented by Orbit MVI. (For more information on how to create an MVI View or MVI Model using Orbit MVI, please check &lt;a href="https://orbit-mvi.org" rel="noopener noreferrer"&gt;here&lt;/a&gt;.)&lt;/p&gt;

&lt;h3&gt;
  
  
  MVI Model
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;InitState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;UiStatus&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InitSideEffect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;Completed&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;InitSideEffect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InitViewModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;fetchAllPokemonUseCase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FetchAllPokemonUseCase&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ContainerHost&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;InitState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;InitSideEffect&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="nc"&gt;ViewModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;container&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;InitState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;InitSideEffect&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;InitState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;init&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stateFlow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="nc"&gt;UiStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Loading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;intent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;reduce&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;UiStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Loading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetchAllPokemonUseCase&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;reduce&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;UiStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nf"&gt;postSideEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InitSideEffect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Completed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;reduce&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;UiStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Failed&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  MVI View
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Composable&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;InitPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;InitViewModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;onCompleted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;state&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stateFlow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collectAsState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nc"&gt;LaunchedEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sideEffectFlow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;InitSideEffect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Completed&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;onCompleted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;Scaffold&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillMaxSize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;UiStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Loading&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nc"&gt;DownloadingMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;
                            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wrapContentSize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;align&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Alignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nc"&gt;UiStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Failed&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nc"&gt;DownloadRetryMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="n"&gt;onRetry&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="n"&gt;modifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Modifier&lt;/span&gt;
                            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wrapContentSize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;align&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Alignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nc"&gt;UiStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://insert-koin.io/docs/reference/koin-android/compose" rel="noopener noreferrer"&gt;Koin | Jetpack Compose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/jetpack/compose/navigation" rel="noopener noreferrer"&gt;Navigation Compose | Navigating With Compose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://orbit-mvi.org/Android-ViewModel/overview" rel="noopener noreferrer"&gt;Orbit MVI | Android ViewModel module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.mindorks.com/mvi-architecture-android-tutorial-for-beginners-step-by-step-guide" rel="noopener noreferrer"&gt;MVI Architecture - Android Tutorial for Beginners - Step By Step Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://coil-kt.github.io/coil/compose/" rel="noopener noreferrer"&gt;Coil | Jetpack Compose&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>jetpackcompose</category>
      <category>orbitmvi</category>
    </item>
    <item>
      <title>Android Mirroring Tool : Release ScrcpyHub v1.5.0</title>
      <dc:creator>katz</dc:creator>
      <pubDate>Wed, 19 Jan 2022 12:02:14 +0000</pubDate>
      <link>https://forem.com/kaleidot725/android-mirroring-tool-release-scrcpyhub-v150-2c0o</link>
      <guid>https://forem.com/kaleidot725/android-mirroring-tool-release-scrcpyhub-v150-2c0o</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;ScrcpyHub is a GUI application to mirror android screen. ScrcpyHub use &lt;a href="https://github.com/Genymobile/scrcpy"&gt;scrcpy&lt;/a&gt;. &lt;a href="https://github.com/Genymobile/scrcpy"&gt;scrcpy&lt;/a&gt; is a mirroring android command tool.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kaleidot725/ScrcpyHub"&gt;https://github.com/kaleidot725/ScrcpyHub&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Features
&lt;/h1&gt;

&lt;p&gt;ScrcpyHub assists in multiple device mirroring. ScrcpyHub makes it easy to do multiple device mirroring.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support Windows10/11 or macOS&lt;/li&gt;
&lt;li&gt;Support light theme and dark theme. 🖼️&lt;/li&gt;
&lt;li&gt;Control mirroing (Start / Stop). 🪞&lt;/li&gt;
&lt;li&gt;Mirror multi android device. 📱&lt;/li&gt;
&lt;li&gt;Save Screenshot. 📸&lt;/li&gt;
&lt;li&gt;Record Movie. 🎥&lt;/li&gt;
&lt;li&gt;Support Tary Menu. 📥&lt;/li&gt;
&lt;li&gt;NEW FEATURE v1.5.0 :Support Linux. 🖥️&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nMVG4m6_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.craft.do/user/full/3a21bd0e-fe7a-39aa-73ad-b52ef24b655b/doc/6B81409B-F369-40D8-A18F-C3EB0794AE95/0198F212-64C1-4528-9DEC-A72EBEED8992_2/LcAfFELCjRs9vCPv2FArMLyGYoeIT37oGJxeO9yi1LMz/demo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nMVG4m6_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.craft.do/user/full/3a21bd0e-fe7a-39aa-73ad-b52ef24b655b/doc/6B81409B-F369-40D8-A18F-C3EB0794AE95/0198F212-64C1-4528-9DEC-A72EBEED8992_2/LcAfFELCjRs9vCPv2FArMLyGYoeIT37oGJxeO9yi1LMz/demo.gif" alt="demo.gif" width="880" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  v1.5.0 New Feature : Support Linux
&lt;/h1&gt;

&lt;p&gt;Support for Linux has been added in v1.5.0. Now you can use ScrcpyHub on Windows, macOS, and Linux desktop OS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3UuDeoUF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.craft.do/user/full/3a21bd0e-fe7a-39aa-73ad-b52ef24b655b/doc/A55138D7-8E5B-4402-9E63-931F9B381135/802F9888-5D6D-42C8-AB09-4E61E542DA4F_2/nFSHjATDvbFp18jLCmNQAS9LxZHWHpsTRviF0wPoMU0z/2022-01-19%252020-53-29.2022-01-19%252020_56_37.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3UuDeoUF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.craft.do/user/full/3a21bd0e-fe7a-39aa-73ad-b52ef24b655b/doc/A55138D7-8E5B-4402-9E63-931F9B381135/802F9888-5D6D-42C8-AB09-4E61E542DA4F_2/nFSHjATDvbFp18jLCmNQAS9LxZHWHpsTRviF0wPoMU0z/2022-01-19%252020-53-29.2022-01-19%252020_56_37.gif" alt="2022-01-19 20-53-29.2022-01-19 20_56_37.gif" width="880" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  How to Use
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;p&gt;Install adb and scrcpy, ScrcpyHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  💻 Windows 10 / 11
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Download &lt;a href="https://github.com/Genymobile/scrcpy#windows"&gt;here&lt;/a&gt; and install scrcpy somewhere.&lt;/li&gt;
&lt;li&gt;Download &lt;a href="https://github.com/kaleidot725/scrcpy-hub/releases/tag/v1.4.0"&gt;here&lt;/a&gt; and launch ScrcpyHub.&lt;/li&gt;
&lt;li&gt;Open ScrcpyHub Preferences.&lt;/li&gt;
&lt;li&gt;Input adb and scrcpy location, save settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  💻 Linux(Ubuntu)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Download &lt;a href="https://github.com/Genymobile/scrcpy#windows"&gt;here&lt;/a&gt; and install scrcpy somewhere.&lt;/li&gt;
&lt;li&gt;Download &lt;a href="https://github.com/kaleidot725/scrcpy-hub/releases/tag/v1.5.0"&gt;here&lt;/a&gt; and install ScrcpHub.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo dpkg -i scrcpyhub_1.5.0_amd64.deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Launch ScrcpyHub, open Preferences.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/opt/scrcpyhub/bin/ScrcpyHub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Input adb and scrcpy location, save settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  💻 Mac OS
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install android-platform-tools and scrcpy.&lt;/li&gt;
&lt;li&gt;Download &lt;a href="https://github.com/kaleidot725/scrcpy-hub/releases/tag/v1.4.0"&gt;here&lt;/a&gt; and launch ScrcpyHub.&lt;/li&gt;
&lt;li&gt;Open ScrcpyHub Preferences.&lt;/li&gt;
&lt;li&gt;Input adb and scrcpy location, save settings.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install android-platform-tools
brew install scrcpy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  🔥Contact
&lt;/h1&gt;

&lt;p&gt;We are working on the development &lt;a href="https://github.com/kaleidot725/ScrcpyHub"&gt;here&lt;/a&gt;.  If you have any suggestions for improvement, please contact us.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
      <category>jetpackcompose</category>
      <category>composefordesktop</category>
    </item>
    <item>
      <title>Android Mirroring Tool : Release ScrcpyHub v1.4.0</title>
      <dc:creator>katz</dc:creator>
      <pubDate>Thu, 13 Jan 2022 07:57:30 +0000</pubDate>
      <link>https://forem.com/kaleidot725/android-mirroring-tool-release-scrcpyhub-v140-33ic</link>
      <guid>https://forem.com/kaleidot725/android-mirroring-tool-release-scrcpyhub-v140-33ic</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;ScrcpyHub is a GUI application to use scrcpy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kaleidot725/ScrcpyHub"&gt;https://github.com/kaleidot725/ScrcpyHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;scrcpy is an Android device screen mirroring command tool. scrcpy is a useful command tool, but multiple device mirroring is so difficult and bother.&lt;/p&gt;

&lt;p&gt;1.Get android device using adb command.&lt;br&gt;
2.Execute scrcpy command using -s option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JLE8rTV7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.craft.do/user/full/3a21bd0e-fe7a-39aa-73ad-b52ef24b655b/doc/6995FDF2-2CF0-43F5-B9D3-C35F739FF92F/BB45EAD5-A33A-4C88-8243-24E6F425A2F6_2/2021-11-27%252011-10-40.2021-11-27%252011_11_40.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JLE8rTV7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.craft.do/user/full/3a21bd0e-fe7a-39aa-73ad-b52ef24b655b/doc/6995FDF2-2CF0-43F5-B9D3-C35F739FF92F/BB45EAD5-A33A-4C88-8243-24E6F425A2F6_2/2021-11-27%252011-10-40.2021-11-27%252011_11_40.gif" alt="2021-11-27 11-10-40.2021-11-27 11_11_40.gif" width="582" height="366"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;ScrcpyHub assists in multiple device mirroring. ScrcpyHub makes it easy to do multiple device mirroring.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support Windows10 / 11 or macOS.&lt;/li&gt;
&lt;li&gt;Detect android device.&lt;/li&gt;
&lt;li&gt;Control mirroing (Start / Stop).&lt;/li&gt;
&lt;li&gt;Save Screenshot.&lt;/li&gt;
&lt;li&gt;Support Tary Menu.&lt;/li&gt;
&lt;li&gt;Record Movie.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;v1.4.0 NEW Feature : Modify light and dark theme.&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nMVG4m6_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.craft.do/user/full/3a21bd0e-fe7a-39aa-73ad-b52ef24b655b/doc/6B81409B-F369-40D8-A18F-C3EB0794AE95/0198F212-64C1-4528-9DEC-A72EBEED8992_2/LcAfFELCjRs9vCPv2FArMLyGYoeIT37oGJxeO9yi1LMz/demo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nMVG4m6_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.craft.do/user/full/3a21bd0e-fe7a-39aa-73ad-b52ef24b655b/doc/6B81409B-F369-40D8-A18F-C3EB0794AE95/0198F212-64C1-4528-9DEC-A72EBEED8992_2/LcAfFELCjRs9vCPv2FArMLyGYoeIT37oGJxeO9yi1LMz/demo.gif" alt="demo.gif" width="880" height="555"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  v1.4.0 New Feature : Modify light and dark theme
&lt;/h2&gt;

&lt;p&gt;v1.4.0 support modifying light and dark theme. You toggle lignt and dark theme. Try it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---JdWMVf1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.craft.do/user/full/3a21bd0e-fe7a-39aa-73ad-b52ef24b655b/doc/6B81409B-F369-40D8-A18F-C3EB0794AE95/60E47A48-C287-48E6-9EE4-770B806F60FD_2/flY22zicUTUBSnXUtOTUXxiDK82kuRyVACE0GDYQY2Yz/2022-01-10%252017-56-07.2022-01-10%252017_56_42.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---JdWMVf1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.craft.do/user/full/3a21bd0e-fe7a-39aa-73ad-b52ef24b655b/doc/6B81409B-F369-40D8-A18F-C3EB0794AE95/60E47A48-C287-48E6-9EE4-770B806F60FD_2/flY22zicUTUBSnXUtOTUXxiDK82kuRyVACE0GDYQY2Yz/2022-01-10%252017-56-07.2022-01-10%252017_56_42.gif" alt="2022-01-10 17-56-07.2022-01-10 17_56_42.gif" width="880" height="555"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  How to Use
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;

&lt;p&gt;Install adb and scrcpy, ScrcpyHub.&lt;/p&gt;
&lt;h3&gt;
  
  
  Mac OS
&lt;/h3&gt;

&lt;p&gt;1.Install android-platform-tools and scrcpy.&lt;br&gt;
2.Download &lt;a href="https://github.com/kaleidot725/scrcpy-hub/releases/tag/v1.4.0"&gt;here&lt;/a&gt; and launch ScrcpyHub.&lt;br&gt;
3.Open ScrcpyHub Preferences.&lt;br&gt;
4.Input adb and scrcpy location, save settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install android-platform-tools
brew install scrcpy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Windows 10 / 11
&lt;/h3&gt;

&lt;p&gt;1.Download &lt;a href="https://github.com/Genymobile/scrcpy#windows"&gt;here&lt;/a&gt; and install scrcpy somewhere.&lt;br&gt;
2.Download &lt;a href="https://github.com/kaleidot725/scrcpy-hub/releases/tag/v1.4.0"&gt;here&lt;/a&gt; and launch ScrcpyHub.&lt;br&gt;
3.Open ScrcpyHub Preferences.&lt;br&gt;
4.Input adb and scrcpy location, save settings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contact
&lt;/h2&gt;

&lt;p&gt;We are working on the development &lt;a href="https://github.com/kaleidot725/ScrcpyHub"&gt;here&lt;/a&gt;. If you have any suggestions for improvement, please contact us.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>android</category>
      <category>jetpackcompose</category>
      <category>composefordesktop</category>
    </item>
    <item>
      <title>Release ScrcpyHub v1.3.0</title>
      <dc:creator>katz</dc:creator>
      <pubDate>Wed, 29 Dec 2021 17:56:21 +0000</pubDate>
      <link>https://forem.com/kaleidot725/release-scrcpyhub-v130-1ho5</link>
      <guid>https://forem.com/kaleidot725/release-scrcpyhub-v130-1ho5</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;ScrcpyHub is a GUI application to use scrcpy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kaleidot725/ScrcpyHub" rel="noopener noreferrer"&gt;https://github.com/kaleidot725/ScrcpyHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;scrcpy is an Android device screen mirroring command tool.　scrcpy is a useful command tool, but multiple device mirroring is so difficult and bother.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get android device using adb command.&lt;/li&gt;
&lt;li&gt;Execute scrcpy command using -s option.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2F6995FDF2-2CF0-43F5-B9D3-C35F739FF92F%2FBB45EAD5-A33A-4C88-8243-24E6F425A2F6_2%2F2021-11-27%252011-10-40.2021-11-27%252011_11_40.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2F6995FDF2-2CF0-43F5-B9D3-C35F739FF92F%2FBB45EAD5-A33A-4C88-8243-24E6F425A2F6_2%2F2021-11-27%252011-10-40.2021-11-27%252011_11_40.gif" alt="2021-11-27 11-10-40.2021-11-27 11_11_40.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;ScrcpyHub assists in multiple device mirroring. ScrcpyHub makes it easy to do multiple device mirroring.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support Windows10 / 11 or macOS.&lt;/li&gt;
&lt;li&gt;Detect android device.&lt;/li&gt;
&lt;li&gt;Control mirroing (Start / Stop).&lt;/li&gt;
&lt;li&gt;Save Screenshot.&lt;/li&gt;
&lt;li&gt;Support Tary Menu.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;v1.3.0 NEW Feature : Record Movie.&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2F6995FDF2-2CF0-43F5-B9D3-C35F739FF92F%2FE0E18CA8-8A5C-4633-B72F-FBA8315D34BD_2%2F2021-11-27%252018-10-59.2021-11-27%252018_12_53.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2F6995FDF2-2CF0-43F5-B9D3-C35F739FF92F%2FE0E18CA8-8A5C-4633-B72F-FBA8315D34BD_2%2F2021-11-27%252018-10-59.2021-11-27%252018_12_53.gif" alt="2021-11-27 18-10-59.2021-11-27 18_12_53.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  New Feature : Record Movie
&lt;/h2&gt;

&lt;p&gt;v1.3.0 support recording movie. You record easily movie with your Android Device. Try it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6bopuihx808fq38sdte.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6bopuihx808fq38sdte.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;

&lt;p&gt;Install adb and scrcpy, ScrcpyHub.&lt;/p&gt;

&lt;h4&gt;
  
  
  💻 Mac OS
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Install android-platform-tools and scrcpy.&lt;/li&gt;
&lt;li&gt;Download &lt;a href="https://github.com/kaleidot725/scrcpy-hub/releases/tag/v1.3.0" rel="noopener noreferrer"&gt;here&lt;/a&gt; and launch ScrcpyHub.&lt;/li&gt;
&lt;li&gt;Open ScrcpyHub Preferences.&lt;/li&gt;
&lt;li&gt;Input adb and scrcpy location, save settings.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install android-platform-tools
brew install scrcpy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  💻 Windows 10 / 11
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Download &lt;a href="https://github.com/Genymobile/scrcpy#windows" rel="noopener noreferrer"&gt;here&lt;/a&gt; and install scrcpy somewhere.&lt;/li&gt;
&lt;li&gt;Download &lt;a href="https://github.com/kaleidot725/scrcpy-hub/releases/tag/v1.3.0" rel="noopener noreferrer"&gt;here&lt;/a&gt; and launch ScrcpyHub.&lt;/li&gt;
&lt;li&gt;Open ScrcpyHub Preferences.&lt;/li&gt;
&lt;li&gt;Input adb and scrcpy location, save settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2F137C802C-F06D-460A-BA71-9B94DAF64B71%2F83AAA09B-F6B5-425C-9CF7-FEA002375072_2%2FImage" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.craft.do%2Fuser%2Ffull%2F3a21bd0e-fe7a-39aa-73ad-b52ef24b655b%2Fdoc%2F137C802C-F06D-460A-BA71-9B94DAF64B71%2F83AAA09B-F6B5-425C-9CF7-FEA002375072_2%2FImage" alt="Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔥Contact
&lt;/h2&gt;

&lt;p&gt;We are working on the development &lt;a href="https://github.com/kaleidot725/ScrcpyHub" rel="noopener noreferrer"&gt;here&lt;/a&gt;. If you have any suggestions for improvement, please contact us.&lt;/p&gt;

</description>
      <category>android</category>
      <category>kotlin</category>
      <category>scrcpy</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
