<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های سپهر تابعیان</title>
        <link>https://virgool.io/feed/@sepehrtabeian</link>
        <description>توسعه دهنده اندروید و فلاتر هستم و هر چیزی که  داخلش خلاقیت وجود داشته باشه برای من جذابه</description>
        <language>fa</language>
        <pubDate>2026-06-15 21:45:23</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/40124/avatar/NPtWMy.jpeg?height=120&amp;width=120</url>
            <title>سپهر تابعیان</title>
            <link>https://virgool.io/@sepehrtabeian</link>
        </image>

                    <item>
                <title>راه‌اندازی Mirror برای Flutter/Dart Pub</title>
                <link>https://virgool.io/flutter-community/%D8%B1%D8%A7%D9%87-%D8%A7%D9%86%D8%AF%D8%A7%D8%B2%DB%8C-mirror-%D8%A8%D8%B1%D8%A7%DB%8C-flutterdart-pub-a2yygoj8jayu</link>
                <description>مسئله چیست؟در فرآیند توسعه با Flutter و Dart، استفاده از پکیجها و بستهها اهمیت زیادی دارد. با این حال، در برخی مواقع ممکن است به دلیل مشکلات شبکه , پروکسی دسترسی به pub.dev (منبع اصلی پکیجها) با اختلال مواجه شود. این مشکلات میتواند ناشی از محدودیتهای اینترنتی، فایروالها یا حتی سرورهای غیرفعال باشد.قطعا با وجود ابزار های دور زدن فیلترینگ تجربه خطاهای ناموفق عدم دانلود پکیج های فلاتری را داشتید و حسابی کلافه شدید خواستید خودتون رو از بالا پرت کنید پایین.یک راه حل کاربردی و امتحان شده برای زمانی که نشت آی پی ایران دارید.اگر هنگام flutter pub get با خطاهایی مثل Authentication error (403) یا مشکلات شبکه روبهرو میشوید، استفاده از Mirror قابلاعتماد میتواند دریافت وابستگیها را پایدارتر کند.راهکار بهصورت خلاصهاستفاده از یک Mirror برای pub به ما این امکان را میدهد تا به جای مراجعه به pub.dev، از یک منبع محلی یا نزدیکتر استفاده کنیم. برای این کار تنها نیاز به یک سوییچ یکفرمانی داریم که به ما اجازه میدهد تا بهراحتی به Mirror متصل شویم.سوییچ سریع بین آینه و منبع رسمی را تنها با یک دستور خواهید داشت.macOS + zsh — پیکربندی دائمی با توضیحات مرحلهبهمرحله1) بررسی شل فعالدر macOS پیشفرض شل zsh است. برای اطمینان:echo $SHELLخروجی معمول: /bin/zsh2) پشتیبانگیری از تنظیمات فعلی شلقبل از هر تغییری از ~/.zshrc بکاپ بگیرید:cp ~/.zshrc ~/.zshrc.bak-$(date +%Y%m%d)3) باز کردن فایل تنظیمات ~/.zshrcبا ویرایشگر دلخواه باز کنید. مثلا با TextEdit:open -e ~/.zshrcیا اگر VS Code دارید:code ~/.zshrc4) افزودن Mirror + سوییچ سریعاین بلوک را عیناً به انتهای فایل اضافه کنید:# &gt;&gt;&gt; PUB MIRROR SWITCH &gt;&gt;&gt;

export PUB_HOSTED_URL=&quot;https://pub.flutter-io.cn&quot;
export FLUTTER_STORAGE_BASE_URL=&quot;https://storage.flutter-io.cn&quot;

alias pub-cn=&#039;export PUB_HOSTED_URL=&quot;https://pub.flutter-io.cn&quot;; export FLUTTER_STORAGE_BASE_URL=&quot;https://storage.flutter-io.cn&quot;; echo &quot;Using mirror: $PUB_HOSTED_URL&quot;&#039;
alias pub-dev=&#039;export PUB_HOSTED_URL=&quot;https://pub.dev&quot;; export FLUTTER_STORAGE_BASE_URL=&quot;https://storage.googleapis.com&quot;; echo &quot;Using upstream: $PUB_HOSTED_URL&quot;&#039;
# &lt;&lt;&lt; PUB MIRROR SWITCH &lt;&lt;&lt;توضیح خطوط:PUB_HOSTED_URL: مبدأ دریافت پکیجهای Dart/Flutter.FLUTTER_STORAGE_BASE_URL: مبدأ دریافت باینریها/آرتیفکتهای Flutter (مانند engine و SDK).pub-cn: در همان شل فعلی سوییچ به Mirror.pub-dev: در همان شل فعلی سوییچ به مبدأ رسمی.5) بارگذاری مجدد تنظیماتبرای اعمال فوری تغییرات:source ~/.zshrc6) راستیآزمایی مبدأهاecho $PUB_HOSTED_URL 
echo $FLUTTER_STORAGE_BASE_URLانتظار در حالت Mirror:https://pub.flutter-io.cnhttps://storage.flutter-io.cn7) استفادهٔ روزمرهاجرای عادی (پس از باز شدن شل جدید، Mirror پیشفرض است):flutter pub getسوییچ صریح به Mirror در همین ترمینال:pub-cn
flutter pub getسوییچ به منبع رسمی در همین ترمینال:pub-dev
flutter pub get8) نکات و رفع اشکال سریعاگر خطا ادامه داشت:flutter clean سپس flutter pub getسوییچ بین Mirror/رسمی: pub-cn یا pub-devبررسی دسترسی ها:curl -I https://pub.dev/api/packages/archive/advisories
curl -I https://pub.flutter-io.cn/api/packages/archive/advisoriesاین تنظیمات تضمین «صفر خطا» نیست؛ آینهها ممکن است گهگاهی کند یا در دسترس نباشند.9) بازگردانی/حذف تغییرات(اختیاری)فایل ~/.zshrc را باز کرده و بلوک افزودهشده را پاک/کامنت کنید، سپس:source ~/.zshrcدر صورت نیاز میتوانید بکاپ را برگردانید:mv ~/.zshrc.bak-YYYYMMDD ~/.zshrc
source ~/.zshrcWindows — پیکربندی دائمی + سوییچ سریعمیتوانید از PowerShell (توصیهشده) یا CMD استفاده کنید. در هر دو حالت، برای دائمیکردن، متغیرهای محیطی سطح کاربر را تنظیم میکنیم.گزینه PowerShell (پیشنهادی)1) تنظیم دائمی (User) به آینهPowerShell را بهصورت عادی باز کنید (بدون نیاز به ادمین برای سطح کاربر):setx PUB_HOSTED_URL &quot;https://pub.flutter-io.cn&quot;
setx FLUTTER_STORAGE_BASE_URL &quot;https://storage.flutter-io.cn&quot;نکته: اثر setx در نشست فعلی دیده نمیشود؛ یک PowerShell جدید باز کنید. اگر میخواهید هماکنون هم اعمال شود:$env:PUB_HOSTED_URL = &quot;https://pub.flutter-io.cn&quot;
$env:FLUTTER_STORAGE_BASE_URL = &quot;https://storage.flutter-io.cn&quot;2) افزودن توابع سوییچ سریع به پروفایل PowerShellساخت/باز کردن پروفایل:New-Item -Type File -Path $PROFILE -Force
notepad $PROFILEاین توابع را در پروفایل بچسبانید تا هر بار با باز شدن PowerShell در دسترس باشند:
function Use-PubMirror {
  $env:PUB_HOSTED_URL = &quot;https://pub.flutter-io.cn&quot;
  $env:FLUTTER_STORAGE_BASE_URL = &quot;https://storage.flutter-io.cn&quot;
  Write-Host &quot;Using mirror: $env:PUB_HOSTED_URL&quot;
}

function Use-PubUpstream {
  $env:PUB_HOSTED_URL = &quot;https://pub.dev&quot;
  $env:FLUTTER_STORAGE_BASE_URL = &quot;https://storage.googleapis.com&quot;
  Write-Host &quot;Using upstream: $env:PUB_HOSTED_URL&quot;
}

function Set-PubMirrorPermanent {
  setx PUB_HOSTED_URL &quot;https://pub.flutter-io.cn&quot; | Out-Null
  setx FLUTTER_STORAGE_BASE_URL &quot;https://storage.flutter-io.cn&quot; | Out-Null
  Write-Host &quot;User env set to MIRROR. Open a new PowerShell.&quot;
}

function Set-PubUpstreamPermanent {
  setx PUB_HOSTED_URL &quot;https://pub.dev&quot; | Out-Null
  setx FLUTTER_STORAGE_BASE_URL &quot;https://storage.googleapis.com&quot; | Out-Null
  Write-Host &quot;User env set to UPSTREAM. Open a new PowerShell.&quot;
}بارگذاری مجدد پروفایل (یا باز کردن پنجره جدید):. $PROFILE3) راستیآزماییدر نشست فعلی:$env:PUB_HOSTED_URL
$env:FLUTTER_STORAGE_BASE_URLمقدار دائمی (User):[Environment]::GetEnvironmentVariable(&quot;PUB_HOSTED_URL&quot;,&quot;User&quot;)
[Environment]::GetEnvironmentVariable(&quot;FLUTTER_STORAGE_BASE_URL&quot;,&quot;User&quot;)4) استفادهٔ روزمرهflutter pub get        # با مقادیر دائمی
Use-PubMirror         # سوییچ فوری به میرور در همین نشست
Use-PubUpstream       # سوییچ فوری به منبع رسمی5) بازگردانی/حذف مقادیر دائمی(اختیاری)[Environment]::SetEnvironmentVariable(&quot;PUB_HOSTED_URL&quot;, $null, &quot;User&quot;)
[Environment]::SetEnvironmentVariable(&quot;FLUTTER_STORAGE_BASE_URL&quot;, $null, &quot;User&quot;)سپس یک PowerShell جدید باز کنید.گزینه Command Prompt &#40;CMD&#41;1) تنظیم دائمی (User) به Mirrorsetx PUB_HOSTED_URL &quot;https://pub.flutter-io.cn&quot;
setx FLUTTER_STORAGE_BASE_URL &quot;https://storage.flutter-io.cn&quot;یک CMD جدید باز کنید تا اثر کند.2) تنظیم موقت در همان نشستset PUB_HOSTED_URL=https://pub.flutter-io.cn
set FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn3) سوییچ سریع با فایلهای batch (اختیاری)یک فایل به نام pub-cn.cmd بسازید و محتوای زیر را در آن قرار دهید:@echo off
set PUB_HOSTED_URL=https://pub.flutter-io.cn
set FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
echo Using mirror: %PUB_HOSTED_URL%یک فایل به نام pub-dev.cmd بسازید:@echo off
set PUB_HOSTED_URL=https://pub.dev
set FLUTTER_STORAGE_BASE_URL=https://storage.googleapis.com
echo Using upstream: %PUB_HOSTED_URL%اگر مسیر این فایلها در PATH باشد، میتوانید در همان CMD اجرا کنید:pub-cn
flutter pub get

pub-dev
flutter pub get4) راستیآزماییecho %PUB_HOSTED_URL%
echo %FLUTTER_STORAGE_BASE_URL%5) بازگردانی/حذف مقادیر دائمی(اختیاری)setx حذف مستقیم ندارد. از PowerShell استفاده کنید:[Environment]::SetEnvironmentVariable(&quot;PUB_HOSTED_URL&quot;, $null, &quot;User&quot;)
[Environment]::SetEnvironmentVariable(&quot;FLUTTER_STORAGE_BASE_URL&quot;, $null, &quot;User&quot;)سپس یک CMD جدید باز کنید.خوشحالم که تا اینجا مقاله را خواندی و امیدوارم کاربردی بوده باشد.نکات مهماین روش پایداری را بهتر میکند، اما تضمین ۱۰۰٪ نیست. اگر آینهها کند شدند، به منبع رسمی برگردید.در CI/CD بهتر است متغیرها را بهطور صریح در محیط همان Job تنظیم کنید تا قابل تکرار باشد.پس از تغییر مقادیر دائمی با setx، همیشه ترمینال جدید باز کنید.اگر پشت پراکسی هستید، تنظیمات پراکسی سیستم/ترمینال را بررسی کنید.می دونید که با ❤️ کردن باعث انگیزه می شوید. منتظر کامنت های شما هستم.حتما تجربه های خودتون را در کامیونیتی فلاتر فارسی به اشتراک بگذارید.</description>
                <category>سپهر تابعیان</category>
                <author>سپهر تابعیان</author>
                <pubDate>Sat, 25 Apr 2026 05:50:36 +0330</pubDate>
            </item>
                    <item>
                <title>تا حالا شده در زبان شی گرا از  class func استفاده کنی؟</title>
                <link>https://virgool.io/flutter-community/class-function-in-swift-csxrb3k3e8z9</link>
                <description>سلامخوشحالم که دوباره فرصت پیدا کردم تا یک مطلب فوق العاده دیگه باهاتون به اشتراک بگذارم.توی زبان swift ما یک چیزی داریم به اسم class func که متفاوت از سینتکس هایی است که تا حالا  در زبان های شی گرا خوندیم.می خوام این مفهوم رو در زبان های سوئیفت و دارت و کاتلین و جاوا بررسی کنم.class A {
  class func firstFunction()  -&gt; String{
      return &amp;quot first &amp;quot}
  func secondFunction ()  -&gt; String{
       return &amp;quot second &amp;quot
}
} اما قبلش یک سری تعریف های ساده رو باهم مرور می کنیم.تعریف class :داخل کلاس می تونیم متغیر ها و متدها رو تعریف کنیمتعریف enum : می تونیم به وسیله enum یک type با مقادیر دلخواه بسازیم و از اونها استفاده کنیم. enum ها را نمی توانیم به ارث ببریم.سینتکس enum هم به این شکل بود.در زبان سوئیفت :enum Gender {
    case female
    case male  
}در زبان دارت : enum Gender {
    female , male 
}در زبان کاتلین البته enum ها از نوع کلاس هستند:enum class Gender {
    FEMALE , MALE  
}در زبان جاوا :enum Gender {
    FEMALE , MALE 
 } فراخوانی enum  هم به این شکل است :Gender.female یا Gender.FEMALEبرای مدل سازی   در زبان های مختلف هم یک سری مفاهیم داریم. مدل سازی در زبان سوئیفت از طریق structure ها انجام میشه که با کلیدstruct  مشخص میشه .اینکه فرق struct با class چیست و چرا در سوئیفت برای مدل سازی از کلاس استفاده نمی کنیم نیاز به توضیحات زیادی داره که توی این پست دربارش حرف نمی زنم اما لازمه بدونید که struct ها را نمی توانیم ارث ببریم.در struct و حتی enum ها یک کپی  از آنها پاس داده می شود اما در کلاس ها رفرنس پاس داده می شود.struct Person{
      var name =  &amp;quot your name &amp;quot
      init(name:String){
            self.name=name
}
}مدل سازی در زبان کاتلین از طریق data class بجای class استفاده می کنیم.data class Person(val name : String) مدل سازی در زبان دارت  تقریبا مثل زبان جاوا است و از کلاس استفاده می کنیم.class Person {
    final name String;
    Person({
         required this.name
}
);
}خب حالا که تا اینجا اومدیم بریم دوتا مفهوم دیگه که در ادامه بهش نیاز داریم را مرور کنیم.تعریف Instance methods :به متد ها یا همون function هایی که در class , struct , enum استفاده می کنیم instance method گفته می شود.در  این متد ها می توانیم به بقیه متغیر ها و متدهای دیگه در کلاس دسترسی داشته باشیم.class Counter {
    var count = 0
    func increment() {
        count += 1
}
     func increment(by amount: Int) {
           count += amount
}
     func reset() {
           count = 0
}
}هر سه متد از نوع instance method هستند. از طریق شی  کلاس Counter به instance method ها دسترسی پیدا می کنیم و در واقع یک instance از type خاص هستند.به عبارتی این متدها متعلق به شی کلاس هستند .let counter = Counter()
// the initial counter value is 0
counter.increment()
// the counter&#039;s value is now 1
counter.increment(by: 5)
// the counter&#039;s value is now 6
counter.reset()
// the counter&#039;s value is now 0تعریف Type methods :برخلاف  instance method که شما از طریق یک type خاص آنها را فراخوانی می کردید در اینجا متدها از طریق type خودشان صدا زده می شوند. در بیشتر زبان ها برای نشان دادن این نوع متد ها کلید static استفاده می کنیم.این متد ها متعلق به کلاس هستند.class SomeClass {
  class func someTypeMethod() {
// type method implementation goes here
}
   static func someType(){
}
}
//call :
SomeClass.someTypeMethod()
SomeClass.someType()همانطور که می بینید  در سوئیفت ما به دو روش می توانیم type method بسازیم که به یک شکل metaType هم فراخوانی شده اند.اما واقعا تفاوت در چیست؟!یک تفاوت جالب وجود دارد. شما نمی توانید متد های استاتیک را توسط کلاس دیگه به ارث ببرید.یعنی متد someType قابل ارث بری نیست.پس برای اینکه هم متد استاتیک داشته باشید و هم بتوانید آنرا به فرزند کلاس بدهید باید از کلید های class func برای اینکار استفاده کنید.یادآوری کنم که اگر می خواستید یک property در type method ها استفاده کنید باید آن   property هم از نوع استاتیک تعریف کنید تا در type method به آن دسترسی داشته باشید.class SomeClass  {
   static var name=&amp;quot Sepehr&amp;quot
   class func someTypeMethod() {
// type method implementation goes here
       name=&amp;quotAhmad&amp;quot
}
    static func someType(){
          name=&amp;quot Ali&amp;quot
}
}وقتی از کلاس SomeClass ارث بری کنیم  داریم :class  Foo : SomeClass {
  override class func someTypeMethod() {
}
}طرح یک پرسش : بنظرتون از class func می توانیم در enum و struct استفاده کنfluentu.comاگر جوابت بله است پیشنهاد می کنم یکبار دیگه این پست رو از اول بخونی  اگر جوابت خیر است بهت تبریک میگم.اصلا class func  زمانی کاربرد دارد  که بخواهیم متد ما هم از نوع استاتیک و هم قابل ارث بری باشد اما در enum ها و struct ها ما ارث بری نداریم.پس در این حالت برای ما کاربردی نیستاما  هنوز می توانیم type method را از طریق کلید static  برای enum و struct تعریف کنیم.حالا که متوجه شدیم class func چه کاربردی در سوئیفت دارد بیایید بررسی کنیم که معادل class func در زبان های دارت و کاتلین و جاوا به چه صورت است؟اصلا شدنی است؟یکبار دیگه مرور کنیم که در زبان های شی گرا متد های استاتیک قابل ارث بری نیستند.پس ما نمی تونیم مثل سوئیفت عمل کنیم که هم متد را به صورت metaType صدا بزنیم و هم بتوانیم آن متد را override کنیم و عملا برای class fun معادلی در دارت و جاوا و کاتلین وجود ندارد.ممنونم که تا آخر این پست با من بودید.خوشحال می شوم اگر موردی هست با من و بقیه به اشتراک بگذارید. لطفا نظر دهید و با ❤️ کردن از من حمایت کنید.مراجع :داکیومنت سوئیفت و stackoverflow.com</description>
                <category>سپهر تابعیان</category>
                <author>سپهر تابعیان</author>
                <pubDate>Sat, 18 Jun 2022 02:19:28 +0430</pubDate>
            </item>
                    <item>
                <title>واقعیت مجازی (VR)در ارتش</title>
                <link>https://virgool.io/@sepehrtabeian/%D9%88%D8%A7%D9%82%D8%B9%DB%8C%D8%AA-%D9%85%D8%AC%D8%A7%D8%B2%DB%8C-vr%D8%AF%D8%B1-%D8%A7%D8%B1%D8%AA%D8%B4-ajhqagczfawi</link>
                <description>ارتش آمریکا خیلی زودتر از بازارهای تجاری، استفاده از Virtual Reality یا همان واقعیت مجازی را شروع کرد. اگر ارتش آمریکا روی تکنولوژی VR میلیارد ها دلار سرمایه گذاری نمی کرد واقعا امروز کسی می دانست که  VR چیست؟ آنها بودند که در توسعه اولین هدست  a.k.a. HMDs  تامین مالی انجام دادند.امروزه پروژه های  صنایع نظامی VR افزایش چشمگیری یافته است و پیش بینی می شود که تا سال 2025 به درآمد هنگفت  1.4میلیارد دلار برسد.کاربردهای نظامی VRدر حال حاضر کاربرد VR در ارتش در زمینه نیروی زمینی،دریایی و هوایی برای پرواز و شبیه سازی میدان جنگ،آموزش پزشکی،شبیه سازی وسایل نقلیه و کمپ های آموزش نظامی است.درحالی که آموزش از طریق  VR همچنان پرکاربردترین و موثرترین گزینه است،ارتش اخیرا برای آنالیز مانورهای نظامی و مواضع میادین جنگی به VR مجهز شده است.1-آموزش از طریق VRاز هر بیست سرباز یک سرباز حین آموزش کشته می شوند.به دلیل  ایجاد افزایش ایمنی و کاهش آمار منفی ، واقعیت مجازی در برنامه های ارتش مورد استقبال قرار گرفت.برخلاف Augmented reality (AR -واقعیت افزوده )،VR مناسب خط مقدم جبهه نبرد نیست.با این حال پتانسیل آموزشی بالاتری دارد زیرا می تواند کاملا موقعیت و شرایط محیطی را برای اهداف عملیاتی شبیه سازی کند.به ویژه برای افزایش مهارت های جنگی سربازان بدون هیج خطر جانی مفید است و ارزان تر از هر مانور نظامی در دنیای واقعی است.انواع آموزش های نظامی VRآموزش غوطه وری :به کارآموزان کمک می کند تا از بین تمام استرس های ناشی از پرش با چتر ، جنگنده ها ، زیردریایی ها و تانک ها عبور کنند(ترس از محیط تنگclaustrophobia)آموزش آگاهی از وضعیت : در ماموریت محیط های خشن مثل جنگل،بیابان،قطب شمال توانایی هدایت و کارتیمی حیاتی است.با ظهور سیستم های وایرلس و قابل حمل VR و با قابلیت حرکات آزادانه، این آموزش ها  واقع بینانه تر شد. اردوهای نظامی مجازی شامل موارد زیر است:یک نمایشگر نصب شده بر روی سر  با  یک ردیابجلیقه مخصوص بار با باتری و کامپیوتر بی سیمردیاب حرکت های بدنسلاح های آموزشی از نظر اندازه ، وزن و شکل برابر با تجهیزات واقعی نظامی است.به عنوان یک مثال عالی این ویدئو  از اداره پلیس نیویورک سیتی (NYPD)را نگاه کنید. https://www.aparat.com/v/rt67e علاوه بر این ،زمینه بعدی مورد استفاده، آموزش پزشکی است.تیم های پزشکی نظامی باید بتوانند در شرایط خطرناک به سرعت و حرفه ای کار کنند.آموزش در بستر VR می تواند تجربه لازم در شرایط جنگی را فراهم کند.2-شبیه ساز های VRبا استفاده از شبیه ساز های VR خلبانان قادر به بررسی محیط های شبیه سازی شده هستند.از جمله آن سناریوهای خطرناکی که در شرایط واقعی  ممکن است در یک هواپیمای واقعی اتفاق بیفتد اما بدون اینکه خودشان یا هواپیما را در معرض خطر قرار دهند.تعداد کمی از فروشندگان شبیه سازهای نظامی مجازی مانند OTR ،مجموعه های کامل سخت افزاری و           نرم افزاری تولید می کنند.کابین خلبان،واحد کنترل و آشنایی با مهارت های لازم در کابین خلبان از جمله  این امکانات است.سیستم رزمی آینده(FCS)،نوع اصلی شبیه سازهاست،بیشتر بر وسایل نقلیه زمینی اعمال می شود، مانند وسایل نقلیه خمپاره اندازها ،نفربر ها و حتی تانک ها و تجهیزات زرهی.VR شرایط محیطی و حرکت قطار در مکان های ناشناخته را بازآفرینی می کند.برخلاف انواع قبلی، VR در نیروی دریایی بر روی شبیه سازی پل فرماندهی کشتی  متمرکز شده است و محیط پیرامون را بازآفرینی می کند.هدف اصلی آن : دریانوردی،جهت یابی، مربی حمل و نقل کشتی(NSST)،شبیه سازی سناریوهایی که در واقعیت ممکن است برای سربازان رخ دهد و ایجاد آمادگی برای مدیریت در سخت ترین شرایط است.پل فرماندهی کشتیدر ایران هم پارک علم و فناوری مازندران موفق به ساخت شبیه ساز پل فرماندهی کشتی شده است.3-درمان از طرق VRتعداد متوسط ​​کهنه سربازان آمریکایی که به زندگی خود پایان می دهند روزانه به 20 نفر رسیده است.      دربیشتر موارد از اختلال اضطراب پس از سانحه  (PTSD) رنج می برند.از سال 2005 واقعیت مجازی در درمان اختلال PTSD مورد استفاده قرار گرفته است.در مراحل ابتدایی،فقط دو محصول تولید شد،افغانستان و عراق مجازی، اما حالا موارد بیشتری موجود است.                                با این اپلیکیشن ها،سربازان صحنه های مختلف نبردی که یکبار بر روان آنها تاثیر گذاشته بود را  تجربه می کنند.    با این حال این کار کاملا ایمن است و هدف آن بهبودی و غلبه بر ترس است.مزایایی واقعیت مجازی در ارتشتأمین امنیت یکی از اصلی ترین مزایای واقعیت مجازی در آموزش نظامی است.علاوه بر این شبیه ساز می تواند برای سناریوهای مختلف  و خطرناک در میدان جنگ آن هم در یک مجموعه کنترل شده مهیا شود.مزایای اصلی عبارتند از :سناریوهای واقعی : بازآفرینی محیط های مشابه محیط های واقعی اما با شرایط 100% کنترل شده.مقرون به صرفه بودن : VR به ما اجازه داد که هزینه های آموزشی کاهش پیدا کند. به دلیل فرسایش  تجهیزات مرتبط و همچنین مسائل لجستیکی این اتفاق دور از انتظار بود.اندازه گیری : بازخورد فوری از جزئیات عملکرد هر شرکت کننده در جنبه های مختلف را بدست می آورید.     از این ابزار برای اصلاح نقاط قوت و ضعف افراد  استفاده می شود.داوطلب شدن بیشتر : با توجه به این واقعیت که بیشتر آموزشهای واقعیت مجازی مانند بازی است ، سربازان از آنها لذت بیشتری می برند. معمولاً به معنای سطح بالاتری از تعامل و درک است.به عنوان چند نمونه : ارتش ایالات متحده امریکا در فورت براگ،کارولینای شمالی در حال توسعه یک اپلیکیشن VR است که سربازان در معرض کمترین خطر جانی و سلامت قرار گیرند.این برنامه به جوخه ها این امکان را می دهد تا تجربه نبرد خود را حفظ کرده و یا برای انجام مأموریت های جدید آماده شوند.استرالیا بودجه گروه فناوری علوم دفاعی  که VR را برای  آموزش نظامی توسعه می دهد  را تأمین می کند. استادان برجسته : روهان واکر و یوجین نالیوایکو با تیم آلبرت ریزو در تلاشند تا هرگونه شرایطی که ممکن است درانتظار سربازان باشد را آماده کنند.از نظر سخت افزاری،توسعه سلاح VR در نوع خود جالب است.شرکت UCVR یک مدل یکسان با  بازوکا اصلی ساخته است که با هدست HTC Vive کار می کند.مجهز به سیستم ویبره بازخورد نیرو،با وزن 2,8 کیلوگرم، با حداکثر 2,100 متر دامنه عملکرد و  با حداکثر دامنه موثر 300 متر .مثال دیگر،Striker VR برای آموزش مهارت های تیراندازی است.این شرکت در تلاش است تا محصول خود را که یک تفنگ VR لمسی است ، به بهترین سیستم بازخورد لمسی در بازار مجهز کند.شامل قابلیت تک شلیک ، مهمات خارج از آن ، سه شلیک پیاپی ، اره برقی ، مواد ضد عفونی کننده  است. یکی دیگر از ویژگی های اسلحه قابلیت جابجایی کامل و حرکت آزاد است.همانطور که می بینیم واقعیت مجازی طیف گسترده ای از کاربردها را در بخش نظامی دارد. این امر ،آموزش نبرد را به سطح بعدی می رساند ، مهارت ها و دانش را فراهم می کند ، اجازه می دهد تا در ایمنی تمرین کنید. همچنین ، به بهبود مهارت های نبرد ،کار تیمی ، آگاهی از وضعیت و مقاومت در برابر فشار روانی کمک می کند. خوشحالم که تا آخر این پست همراه من بودید :) .اگر این مطلب را دوست داشتید لطفا نظر دهید و با ❤️ کردن من را خوشحال کنید.  </description>
                <category>سپهر تابعیان</category>
                <author>سپهر تابعیان</author>
                <pubDate>Fri, 12 Mar 2021 16:11:43 +0330</pubDate>
            </item>
                    <item>
                <title>واقعا داخل RecyclerView چه اتفاقاتی می افتد؟</title>
                <link>https://virgool.io/@sepehrtabeian/%D9%88%D8%A7%D9%82%D8%B9%D8%A7-%D8%AF%D8%A7%D8%AE%D9%84-recyclerview-%DA%86%D9%87-%D8%A7%D8%AA%D9%81%D8%A7%D9%82%D8%A7%D8%AA%DB%8C-%D9%85%DB%8C-%D8%A7%D9%81%D8%AA%D8%AF-r3pmvzcrr7oi</link>
                <description>Image reference: Microsoft docs زندگی توسعه دهنده های اندروید اطراف کار با RecyclerView  می چرخد مانند لیستی از محصولات یک فروشگاه ،لیست مخاطبان،لیست پست های اینستاگرام،لیست خبرهای یک اپ خبری و ... همه  برای نمایش حجم زیادی از دیتا به کاربر از RecyclerView استفاده می کنند.واقعا تا حالا کنجکاو نشدید که RecyclerView  چطوری کار می کند؟چطوری جریانی از دیتا رو به کاربر نمایش می دهد؟چرا ما باید از تمام این عوامل اطلاع داشته باشیم؟فقط به این فکر کنید که تمام اپلیکیشن های اندرویدی مدرن تقریبا از RecyclerView استفاده می کنند،بنابراین نحوه کار با آن بر تجربه میلیون ها کاربر اندرویدی تاثیر می گذارد.ما حتما درباره اینکه  &quot; دیتا چطوری توسط RecyclerView  نمایش داده می شود &quot;  آموزش های خوب زیادی پیدا می کنیم. اما آیا “black box” برای حل سناریو های پیچیده آن هم در حالی که ما میلیون ها دستگاه اندرویدی با rendering و performance متفاوتی داریم رویکرد مناسبی است؟!من قطعا یک تجربه  کاربری بد در  صفحه خانه (یا هر صفحه دیگری)  که در حال حاضر  لیستی از محصولات پیشنهادی را نمایش می دهد برای کاربرانم نمی خواهم.یک نقل قول معروف از بنجامین فرانکلین درباره یادگیری هست :” Tell me and I forget, teach me and I may remember, involve me and I learn” اما قبل اینکه به درون RecyclerView  ورود کنیم ما باید بفهمیم که چرا با وجود ListView ما سراغ RecyclerView  می رویم.با ListView ما یک سری نکات منفی داشتیم:تاخیر در پیمایش(Lag in Scrolling):  به تعداد آیتم های دیتا که درون data-set ما است ListView میاد و view ( ردیف ) می سازد.ساخت view ها و استفاده از متد findViewById پرهزینه است.البته با نوشتن منطق می توانیم عملکرد(performance ) در  ListView را بهبود ببخشیم.پشتیبانی از انیمیشن های پیشفرض وجود نداشت :  ListView با عدم پشتیبانی از انیمیشن ساخته شد و ما می دانیم برای اینکه خودمان یک انیمیشن خوب ست کنیم چقدر زمان باید صرف کنیم.پیمایش فقط در یک جهت( عمودی ) : ListView فقط از پیمایش عمودی پشتیبانی می کند و پیمایش افقی مجاز نیست.به غیر از موارد ذکر شده بالا موارد دیگه هم هست که توسعه دهندگان اندروید را  این نتیجه رساند که بهینه سازی و کارایی های بیشتری نیاز است. از RecyclerView چه می دانیم؟طبق داکیومنت های اندروید : RecyclerView  یک جزئی از UI است که به ما اجازه پیمایش  می دهد.اساسا یک ViewGroup جدید است و برای ارائه هر view که بر پایه adapter است  از آن  در حالت های horizontal/vertical /grid /staggered grid با استفاده از الگوی Viewholder  استفاده می شود.اصطلاحات جدید زیادی وجود داره؟  لطفا گیج نشید و به من چند لحظه اجازه دهید تا توضیح بدم :Image reference: Google ما چهار تا جز اصلی در RecyclerView  داریم : جز اول  RecyclerView.Adapter: وظیفه binding از دیتاسورس به آیتم ها ( که درونRecyclerView  نمایش می دهد ) را به عهده دارد.آداپتر می داند که position آیتم های view درون RecyclerView  را  چطور به یک مکان خاص درون دیتاسورس مرتبط کند .جز دوم RecyclerView.ViewHolder: به ما  در ترسیم UI کمک می کند تا بتوانیم آیتم های اختصاصی خودمان را روی صفحه ترسیم کنیم و استفاده از آن اجباری است.جز سوم RecyclerView.LayoutManager:  نحوه چیدمان آیتم ها درون RecyclerView  را مشخص    می کند.شما می توانید از layout manager های از پیش تعریف شده یا از layout manager شخصی سازی شده استفاده کنید که میشه به صورت linear  یا grid  باشه.جز چهارمRecyclerView.ItemAnimator: یک سری انیمیشن پیش فرض درون RecyclerView وجود دارد که ما می توانیم آن ها را override کنیم و طبق نیاز آنها را تغییر دهیم که به صورت پیش فرض از DefaultItemAnimator استفاده می شود.حالا بیایید و همه این ها را با یک مثال خوشمزه درک کنیمفرض کنید با هم در مقابل یک کیوسک فلافل ایستادیم و یک صف عظیم وجود دارد و  همزمان فقط 4 نفر    می توانند وارد شوند و سفارش دهند.آنجا شخصی وجود دارد که برای هر 4 نفری که وارد می شوند بشقاب                  تهیه می کند.راه دیگش اینه که اون شخص بشقاب های اضافی را دستش نگه دارد و پیشاپیش به افراد در صف و دو نفری که فلافل را تمام کردند و ممکن است دوباره سفارش دهند بشقاب دهد.آن هایی هم که فلافلشان را خوردند بشقاب ها را تحویل فروشنده می دهند تا آن را تمیز کند و به دو نفر جدید بدهد.mage Reference: Google    خب در اینجا فروشنده RecyclerView است، بشقاب ها view ها هستند، فلافل ها همان data هستند                          چهار نفری که همزمان وارد می شوند (visible) ،  Viewport در RecyclerView  است و ایده استفاده کمتر از بشقاب ها همان ViewHolder است. شخصی آنها را تمیز می کند و هروقت که نیاز شد دوباره از آنها       استفاده می کند.این مزیت اصلی استفاده از ViewHolder است و دیگه CPU روی ساختن view ها تمرکز ندارد  و اینطوری task ها کاهش پیدا می کند.امیدوارم با اصطلاحات آشنا شده باشید.حالا اجازه دهید بریم سراغ جزئیات.                              چطوری RecyclerView  کار می کند؟بیایید روند کار رو درک کنیم:Image reference: Microsoft خب،data (آیتم) درون data-set (لیست آیتم ها) نگهداری می شود.آداپتر هم data را به view ها متصل می کند و سپس آنها را به layout manager  می دهد تا view ها کنترل شوند.جالبه بدانید که RecyclerView به هر آیتمی که در دیتاسورس است ، یک item view اختصاص نمی دهد.در عوض فقط مختص به تعدادitem view های صفحه نمایش (Viewport) است .وقتی view  برای اولین بار از دید خارج می شود همانطور که در دیاگرام بالا نشان داده شده است،فرآیند بازیافت طی می شود:وقتی view پیمایش می شود و از  دید خارج می شود به آن  scrap view میگیم.بیایید Scrap view را بیشتر درک کنیم.Recycler برای ذخیره سازی این نوع view ها  Scrap Heap دارد:خب حالا این چیه؟این یک کالکشن سبک است، از آنجا که  دیتا هنوز  به ViewHolder  متصل است  view ها می توانند بدون برگشت به آداپتر، مستقیما به Layout Manager بروند  .بنابراین برای binding نیازی به انتقال مجدد دیتا به آداپتر  نیست.View هایی که اینجا قرار داده شدند موقتا جدا می شودند اما درونlayout یکسان دوباره استفاده می- شوند. ویو در بالا و پایین Viewport از نوع view های جدا شده هستند.انتظار می رود که این ویو های جدا شده قبل از بازگشت کد مجددا متصل شود. یک آیتم جدید وقتی که می خواهد نمایش داده شود یک ویو را از درون recycle pool برمی دارد .از آنجا که این ویو قبل از اینکه نمایش داده شود  دوباره باید  توسط آداپتر  به سر جای اول خود برگردد،         (re-bound) در اصطلاح به این ویو dirty view می گویند.مشابه  Scrap heap که در بالا اشاره شد،برای این نوع ویو ها یک سیستم ذخیره سازی به اسم Recycle Pool داریم.خب حالا باز این چیه؟!یک کالکشن متشکل از ویوهایی است که فرض می شود دیتا نادرستی (دیتا با position یا index متفاوت) دارند که بهش میگیم dirty view.این ویو ها همیشه به آداپتر پاس داده می شود که دیتا بتواند به ViewHolder متصل شود و درنهایت به Layout Manager برگردد.در برخی از موارد یک نمونه از  Recycler به  Layout Manager داده می شود که بتواند ویو های قدیمی یا ویوهای جدید را بازیابی کند.حالا برگردیم به  ادامه dirty view . لطفا ادامه دهید تا با هم به درک بیشتری برسیم :ویو کثیف(dirty view) بازیابی شده  :آداپتر برای آیتم بعدی که قرار است نمایش داده شود ، دیتا را  در موقعیت قرار می دهد و این دیتا برای ویوهای این  آیتم کپی می کند. در ضمن منابع مربوط به این ویو ها  از view holder می آید. لیست آیتم های در شرف نمایش  RecyclerView از ویوهای بازیابی شده  اضافه می شود.وقتی که کاربر برای رفتن به  آیتم بعدی لیست ،عمل پیمایش را انجام  دهد  ویو های بازیابی شده روی صفحه نمایش ظاهر می شوند.در همین حال ویو دیگری که دور از چشم پیمایش می شود مطابق مراحل بالا بازیابی می شود.هر دفعه که آداپتر یک item-layout را inflate می کندViewHolder مربوط به آن را هم  می سازد.ViewHolder از  FindViewById برای ارجاع دادن ویو های درون  Item-layout های inflate  شده  استفاده می کند.هر دفعه که layout ما برای نمایش دیتای جدید  بازیابی شود از این ارجاعات برای دادن دیتای جدید به ویو استفاده می شودمتدهای RecyclerView :هنگامی که شما یک RecyclerView.Adapter را پیاده سازی می کنید باید متدهای زیر را override کنید :زمانی که موقعیت آیتم ها درون RecyclerView تعیین شد حالا layout manager این متد ها را صدا می زند.اگر layout manager نتواند یک ویو  پیدا کند، با صدا زدن متد onCreateViewHolder از آداپتر  یک ویو می سازد .اگر لازم بود یک ویو را از طریق متد onBindViewHolder بایند می کند و در آخر یک ویو بر می گرداند.اطلاع رسانی تغییرات در RecyclerView :متد NotifyDataSetChanged :یک سیگنال برای زمانی که دیتا ست شما تغییر کرده است(اجبار در بروز رسانی کامل )متد NotifyItemChanged : یک سیگنال برای زمانی که یک آیتم با موقعیت خاص تغییر کرده است.متد NotifyItemRemoved : یک سیگنال برای زمانی که  یک آیتم با موقعیت خاص حذف شده است.مانند این داریم: notifyItemRangeInserted ،notifyItemRangeRemoved وnotifyItemRangeChangedدرباره این موارد بالا خودتون مطالعه کنید .اگر  دقیقا بدانید که  دیتای شما چگونه تغییر کرده است می توانید از موارد بالا یک متد مناسب برای رفرش کردنRecyclerView صدا بزنید.برخی نکات درباره کارایی بیشتر RecyclerView :متدrecyclerView.setHasFixedSize(true): اگر  احتمال می دهید که طول و عرض آیتم در XML تغییر نمی کند و  اندازه محتویات RecycerView ثابت است می توانید این خط را به متدهای مقدار دهی اولیه شده RecyclerView اضافه کنید.این متد به RecyclerView میگه که سایز آیتم های من ثابت است و  دیگر نیاز نیست که هردفعه که آیتم ها از RecyclerView حذف یا اضافه می شوند  دوباره محاسبات اندازه XML انجام .شودمتد recyclerView.setItemViewCacheSize(size): قبل از اینکه  ویو های خارج از صفحه  به استخر بازیابی ویو ها بروند شما تعداد  ویو های خارج از صفحه را مشخص کنید. وقتی که RecyclerView را پیمایش می کنید ویویی وجود دارد که از صفحه خارج شده است،RecyclerView آن را  نگه خواهد داشت .اگر شما به عقب پیمایش کنید می توانید بدون اجرای مجدد onBindViewHolder به ویو برسید.چک کنید که چطور و چه زمانی می توانیم از dapter.setHasStableIds(true) استفاده کنیم: از این  متد می توان به انیمیشن و ماندگاری شی  کمک کرد.. همه این ها بکنار ، امیدوارم چیزی یاد گرفته باشید.خوشحالم  که تا آخر این پست همراه من بودید  :) .اگر این مطلب را دوست داشتید لطفا نظر دهید و  با ❤️ کردن  من رو خوشحال کنید.مراجع:ریسایکلرویو ،ListView و آناتومی ریسایکرویو</description>
                <category>سپهر تابعیان</category>
                <author>سپهر تابعیان</author>
                <pubDate>Mon, 08 Mar 2021 18:42:15 +0330</pubDate>
            </item>
            </channel>
</rss>