Vous êtes sur la page 1sur 51

‫ﻣﺴﺎر اﻷﻧﺪرﻳﻮد‬

‫ﻣﻠﺨﺺ اﻟﺪروس‬

‫م‪ /‬ﻣﺤﻤﺪ اﻟﻤﻬﻴﺰع‬


‫ﺗﻠﺨﻴﺺ‬
‫‪@Mohammed.Jassim‬‬

‫ا‪G‬ﺳﺘﺎذ ‪ /‬ﺣﺴﻦ ﻳﻮﺳﻒ‬


‫ﻣﺮاﺟﻌﺔ‬
‫‪@Hassan_Youssef_Tutor‬‬

‫ﻫﻞ اﺳﺘﻔﺪت ﻣﻦ ﻫﺬا اﻟﻤﻠﺨﺺ؟ أرﺟﻮا ﻣﻨﻚ ﻧﺸﺮه ﻗﺪر ﻣﺎ ﺗﺴﺘﻄﻴﻊ‬


‫اﻟﻤﺤﺘﻮى‬

‫‪21‬‬ ‫‪INHERITANCE‬‬ ‫‪ 27‬أﺳﻠﻮب اﻟﺘﻮرﻳﺚ‬ ‫‪1‬‬ ‫‪ 1‬ﻗﻮاﻋﺪ ﻋﺎﻣﺔ ﻓﻲ ﻛﺘﺎﺑﺔ ﻛﻮدات ‪XML‬‬

‫‪22‬‬ ‫‪RED LINES‬‬ ‫‪ 28‬اﻟﺨﻄﻮط اﻟﺤﻤﺮاء‬ ‫‪3‬‬ ‫‪ 2‬ﻋﻨﺎﺻﺮ اﻟﻌﺮض وﻋﺮض اﻟﺘﺨﻄﻴﻂ‬

‫‪22‬‬ ‫‪ 29‬ﻣﺘﻼزﻣﺔ اﻹﺣﺘﻴﺎل ‪IMPOSTER SYNDROME‬‬ ‫‪3‬‬ ‫‪ 3‬ﻣﺜﺎل ﺗﻮﺿﻴﺤﻲ ﻟﻮزن اﻟﺘﺨﻄﻴﻂ‬

‫‪22‬‬ ‫‪ 30‬اﻟﺤﺼﻮل ﻋﻠﻰ أرﻗﺎم ﺳﺎﻟﺒﺔ ﻓﻲ ﺟﺎﻓﺎ‬ ‫‪5‬‬ ‫‪ 4‬اﻟﺘﺨﻄﻴﻂ اﻟﻨﺴﺒﻲ واﻹﺳﻢ اﻟﻤﻌﺮف ‪ID‬‬
‫‪23‬‬ ‫‪INTENT‬‬ ‫‪ 31‬أﺳﻠﻮب اﻟﻤﻘﺼﺪ أو اﻟﻮﺟﻬﺔ‬ ‫‪6‬‬ ‫‪ 5‬ﻣﺜﺎل ﺗﻮﺿﻴﺤﻲ ﻟﻠﺘﺨﻄﻴﻂ اﻟﻨﺴﺒﻲ‬

‫‪25‬‬ ‫‪ 32‬اﻟﺘﻨﺴﻴﻘﺎت واﻟﺴﻤﺎت ‪STYLES & THEMES‬‬ ‫‪7‬‬ ‫‪ 6‬اﻟﻬﻮاﻣﺶ واﻟﺤﺸﻮ ‪MARGINS & PADDINGS‬‬
‫‪26‬‬ ‫‪MAINFEST.XML‬‬ ‫‪ 33‬ﺷﺮح ﻣﻠﻒ اﻟﻮاﺟﻬﺔ‬ ‫‪8‬‬ ‫‪ 7‬ﺧﻄﻮات ﺗﺼﻤﻴﻢ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ‬

‫‪27‬‬ ‫‪ALTERNATIVE RES.‬‬ ‫‪ 34‬اﻟﻤﻮارد اﻟﺒﺪﻳﻠﺔ‬ ‫‪8‬‬ ‫‪ 8‬اﺧﺘﺒﺮ ﻧﻔﺴﻚ ‪ -‬ﺗﺤﺪﻳﺪ ﻧﻮع اﻟﺘﺨﻄﻴﻂ‬

‫‪29‬‬ ‫‪CLASS TYPES‬‬ ‫‪ 35‬أﻧﻮاع اﻷﺻﻨﺎف‬ ‫‪9‬‬ ‫‪ 9‬ﺗﻤﺮﻳﻦ ﻋﻠﻰ اﻟﺘﺨﻄﻴﻂ اﻟﻨﺴﺒﻲ‬

‫‪30‬‬ ‫‪EVENTS LISTENER‬‬ ‫‪ 36‬ﻣﺴﺘﻤﻊ اﻷﺣﺪاث‬ ‫‪10‬‬ ‫‪ 10‬ﻣﻨﺎﻗﺸﺔ ﺣﻮل اﻷداة ‪CONSTRAINT LAYOUT‬‬
‫‪31‬‬ ‫‪ARRAYS, ARRAYSLIST‬‬ ‫‪ 37‬اﻟﻤﺼﻔﻮﻓﺎت‬ ‫‪11‬‬ ‫‪ 11‬ﻛﻴﻒ ﺗﺨﺘﺎر ﺑﺮﻣﺠﺔ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ ‪API‬‬
‫‪33‬‬ ‫‪ 38‬اﻟﺤﻠﻘﺎت اﻟﻤﺴﺘﻤﺮة ‪WHILE, FOR LOOPS‬‬ ‫‪11‬‬ ‫‪ 12‬ﻗﻮاﻋﺪ إدراج اﻟﺼﻮر ﻟﻠﺘﻄﺒﻴﻖ‬

‫‪34‬‬ ‫‪MEMORY RESOURCES‬‬ ‫‪ 39‬ﻣﻮارد اﻟﺬاﻛﺮة‬ ‫‪12‬‬ ‫‪ 13‬ﻣﻘﺪﻣﺔ ﺑﺮﻣﺠﺔ ﻣﻠﻔﺎت ﺟﺎﻓﺎ‬

‫‪34‬‬ ‫‪VIEW RECYCLING‬‬ ‫‪ 40‬ﻋﻨﺼﺮ إﻋﺎدة اﻟﺘﺪوﻳﺮ‬ ‫‪12‬‬ ‫‪ 14‬ﻣﺜﺎل رﺑﻂ ﻋﻨﺼﺮ واﺟﻬﺔ ﺑﻜﻮدات ﺟﺎﻓﺎ‬

‫‪35‬‬ ‫‪ 41‬ﻫﻞ ﺗﺤﺘﺎج إﻟﻰ ﻋﻨﺼﺮ إﻋﺎدة اﻟﺘﺪوﻳﺮ؟‬ ‫‪13‬‬ ‫‪COMMENTS‬‬ ‫‪ 15‬ﻗﻮاﻋﺪ ﻛﺘﺎﺑﺔ اﻟﻤﻼﺣﻈﺎت‬

‫‪35‬‬ ‫‪LISTVIEW + ARRAYADAPTER‬‬ ‫‪ 42‬اﻟﻘﺎﺋﻤﺔ‬ ‫‪14‬‬ ‫‪ 16‬ﻗﻮاﻋﺪ اﻟﻤﺘﻐﻴﺮات وﺷﺮوﻃﻬﺎ‬

‫‪36‬‬ ‫‪CUSTOM CLASS‬‬ ‫‪ 43‬ﺻﻨﻒ ﻣﺨﺼﺺ‬ ‫‪15‬‬ ‫‪ 17‬اﻟﻜﻠﻤﺎت اﻟﻤﻔﺘﺎﺣﻴﺔ اﻟﻤﺤﺠﻮزة ‪KEYWORDS‬‬
‫‪38‬‬ ‫‪ 44‬ﺧﻄﻮات اﻟﺘﻌﺪﻳﻞ ﻋﻠﻰ ﺗﻄﺒﻴﻖ‬ ‫‪15‬‬ ‫‪DEBUGGING‬‬ ‫‪ 18‬ﻛﻴﻔﻴﺔ ﺗﺼﺤﻴﺢ اﻷﺧﻄﺎء‬

‫‪41‬‬ ‫‪MEDIA PLAYER‬‬ ‫‪ 45‬ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ‬ ‫‪16‬‬ ‫‪VARIABLES SCOPE‬‬ ‫‪ 19‬ﻣﺠﺎل اﻟﻤﺘﻐﻴﺮات‬

‫‪42‬‬ ‫‪ 46‬ﻓﺎﺋﺪة اﻷﺳﻠﻮب )(‪toString‬‬ ‫‪16‬‬ ‫‪ 20‬اﻟﻤﺨﻄﻄﺎتاﻟﻤﺘﺪاﺧﻠﺔ ‪NESTED VIEWGROUPS‬‬


‫‪43‬‬ ‫‪ 47‬اﻹﺳﺘﺪﻋﺎء ﻏﻴﺮ اﻟﻤﺘﺰاﻣﻦ ‪ASYNC CALLBACKS‬‬ ‫‪17‬‬ ‫‪STRINGS ROLES‬‬ ‫‪ 21‬ﻗﻮاﻋﺪ ﻛﺘﺎﺑﺔ اﻟﻨﺼﻮص‬

‫‪44‬‬ ‫‪ACTIVITY CYCLE‬‬ ‫‪ 48‬دورة ﺣﻴﺎة اﻟﻨﺸﺎط‬ ‫‪17‬‬ ‫‪ 22‬ﺷﺮح اﻟﻄﺮق وﻛﻴﻔﻴﺔ اﺳﺘﺨﺪاﻣﻬﺎ ‪Methods‬‬
‫‪45‬‬ ‫‪ 49‬ﺗﺮﻛﻴﺰ اﻟﺼﻮت و ‪AUDIOMANAGER‬‬ ‫‪18‬‬ ‫‪ 23‬ﺷﺮح ﻣﻠﻔﺎت وﻣﺠﻠﺪات اﻷﻧﺪرﻳﻮد اﺳﺘﻮدﻳﻮ‬

‫‪47‬‬ ‫‪TOUCH FEEDBACK‬‬ ‫‪ 50‬اﻹﺳﺘﺠﺎﺑﺔ ﻟﻠﻤﺲ‬ ‫‪19‬‬ ‫‪ 24‬ﻛﻴﻔﻴﻚ رﺑﻂ اﻟﻤﻮارد ﺑﻤﻠﻔﺎت ﺟﺎﻓﺎ‬

‫‪X‬‬ ‫‪APPENDICES‬‬ ‫‪ 51‬ﻣﻠﺤﻘﺎت‬ ‫‪20‬‬ ‫‪ 25‬ﻣﺎ اﻟﺬي ﻳﺤﺼﻞ ﺑﻴﻦ ‪ XML‬و ‪JAVA‬‬
‫‪20‬‬ ‫‪JAVA OBJECTS‬‬ ‫‪ 26‬ﺷﺮح ﻛﺎﺋﻨﺎت ﺟﺎﻓﺎ‬
‫‪CAMEL CASE WRITING ROLES‬‬ ‫ﻃﺮﻳﻘﺔ اﻟﻜﺘﺎﺑﺔ ﺑﺄﺳﻠﻮب )‪(Camel Case‬‬
‫ﻫﻲ ﻃﺮﻳﻘﺔ ﻛﺘﺎﺑﺔ ﻟﻜﻠﻤﺎت دﻻﻟﻴﺔ ﻣﺘﻼﺻﻘﺔ ﺑﺤﻴﺚ ﺗﻜﻮن اﻷﺣﺮف اﻷوﻟﻰ ﻣﻦ ﻛﻞ ﻛﻠﻤﺔ ﺑﺎﻷﺣﺮف‬
‫اﻹﻧﺠﻠﻴﺰﻳﺔ اﻟﻜﺒﻴﺮة ‪ Capital Letter‬ﻣﻦ دون وﺟﻮد ﻣﺴﺎﻓﺎت أو رﻣﻮز‪.‬‬
‫ﻣﺜﺎل ذﻟﻚ‪:‬‬
‫ﺷﺨﺺ اﺳﻤﻪ ‪mohammed ali‬‬
‫ﻓﺈﻧﺎ ﻧﻜﺘﺐ اﺳﻤﻪ ﺑﻄﺮﻳﻘﺔ ‪ Camel Case‬ﻫﻜﺬا )‪(MohammedAli‬‬
‫وﺗﺴﺘﺨﺪم ﻫﺬه اﻟﻄﺮﻳﻘﺔ ﻓﻲ اﻟﺘﻌﺒﻴﺮ ﻋﻦ اﻟﻜﻠﻤﺎت ﻓﻲ ﻟﻐﺔ ﺗﺼﻤﻴﻢ واﺟﻬﺔ اﻷﻧـﺪروﻳﺪ ﻣﺜﻼ ﻟﺘﻌﺮﻳـﻒ ﻋﻨﺼـﺮ ﻣﻦ ﻧـﻮع ﻧـﺺ‬
‫ﻟﻌﺮض اﻟﻨﺼﻮص ﻓﺈن اﻟﺘﻌﺒﻴﺮ ﻟﻪ ﻳﻜﺘﺐ ﻫﻜﺬا ‪TextView‬‬

‫‪XML SYNTAX‬‬ ‫ﻗﻮاﻋـﺪ ‪XML‬‬


‫ﻫﻰ ﻗﻮاﻋﺪ ﺗﺤﺪد ﺻﺤﺔ ﻛﻮدات اﻟـ ‪ ، XML‬ﻓﺄﻛﻮاد اﻟـ‪ XML‬ﻓﻲ ﺗﺼﻤﻴﻢ واﺟﻬﺎت اﻷﻧﺪرﻳﻮد ﺗﺤﻤﻞ اﻟﻘﻮاﻋﺪ اﻟﺘﺎﻟﻴﺔ‪:‬‬

‫<‬ ‫‪ViewType‬‬ ‫‪Attributes‬‬ ‫>‪/‬‬


‫ﻓﺘﺢ ﻗﻮس‬ ‫ﻧﻮع اﻟﻌﺮض‬ ‫اﻟﻤﻤﻴﺰات‬ ‫ﻗﻮس إﻏﻼق‬

‫‪<TextView‬‬
‫"‪android:text="Hello‬‬
‫"‪      android:layout_height="wrap_content‬‬ ‫ﻣﺜﺎل‬
‫"‪      android:layout_width="wrap_content‬‬
‫>‪/‬‬

‫‪XML TAGS CLOSING WAYS‬‬ ‫ﻃﺮق إﻏﻼق ﻛﻮد ‪XML‬‬


‫وﺳـــﻢ إﻏـــﻼق وﻓﺘـــﺢ ﻣﻨﻔﺼــﻞ واﻟﻔﺮق ﺑﻴﻨﻬﻤﺎ أﻧﻪ ﻓﻲ داﻟﺔ اﻟﻔﺘﺢ واﻹﻏﻼق‬ ‫وﺳﻢ إﻏﻼق ذاﺗﻲ‬
‫‪ Separate Opening Closing Tags‬اﻟﻤﻨﻔﺼﻞ واﻟﺘﻲ ﻋﺎدة ﻣﺎ ﺗﺴﺘﺨﺪم ﻟﺘﺨﻄﻴﻂ‬
‫‪2‬‬ ‫‪Self Closing Tag‬‬
‫‪1‬‬
‫>‪ <TextView>….. </TextView‬اﻟﺘﺼﻤﻴﻢ ‪ Layout‬ﻳﻤﻜﻦ أن أﺿﻊ ﻋﻨﺎﺻﺮ أﺧﺮى داﺧﻠﻬﺎ‬ ‫>‪<TextView ….. /‬‬
‫>‪ <LinerLayout>….. </LinerLayout‬ﻛﺄن أﺿﻊ ﻣﺜﻼ ‪ TextView‬داﺧﻞ اﻟــ ‪LinearLayout‬‬

‫‪DETERMINING CODING MISTAKES STEPS‬‬ ‫ﺧﻄﻮات ﺗﺤﺪﻳﺪ اﻷﺧﻄﺎء اﻟﺒﺮﻣﺠﻴﺔ‬

‫ﻗﺮاءة رﺳﺎﻟﺔ اﻟﺨﻄﺄ ﺑﺪﻗﺔ وﻣﻌﺮﻓﺔ اﻟﺴﻄﺮ اﻟﺬي ﻳﻜﻮن ﻓﻴﻪ اﻟﺨﻄﺄ إن ﺗﻢ ﺗﺤﺪﻳﺪه ﻓﻲ اﻟﺮﺳﺎﻟﺔ‪.‬‬ ‫‪1‬‬
‫اﺳﺘﺨﺪام اﻟـ ‪ logcat‬ﻓﻲ ﺗﺘﺒﻊ اﻷﺧﻄﺎء‬ ‫‪3‬‬ ‫اﺳﺘﺨﺪام ادوات اﻟﺘﺼﺤﻴﺢ ﻓﻰ اﻟﻨﺪروﻳﺪ اﺳﺘﺪﻳﻮ ‪Debugging Tool‬‬ ‫‪2‬‬
‫اﺳﺘﺨﺪام ﺧﺎﺻﺔ اﻟﺘﺮاﺟﻊ ﻋﻦ اﻟﻜﺘﺎﺑﺔ ‪.‬‬ ‫‪5‬‬ ‫ﻣﻘﺎرﻧﺔ اﻟﻜﻮدات ﺑﻜﻮد آﺧﺮ ﻣﺸﺎﺑﻪ ﻓﻌﺎل وﻻ ﻳﺤﺘﻮي أﺧﻄﺎء‪.‬‬ ‫‪4‬‬
‫ﻃﻠﺐ اﻟﻤﺴﺎﻋﺪة ﻣﻦ اﻟﻤﺒﺮﻣﺠﻴﻦ ﻓﻲ اﻟﻤﻨﺘﺪﻳﺎت أو ﻏﻴﺮه ﻣﻦ وﺳﺎﺋﻞ اﻟﺘﻮاﺻﻞ‪.‬‬ ‫‪6‬‬

‫‪ATTRIBUTES‬‬ ‫اﻟﺨﺼﺎﺋﺺ أو اﻟﺼﻔﺎت أو اﻟﻤﻤﻴﺰات‬

‫ﻣﺜﺎل "‪android:text="Hello‬‬ ‫وﻫﻲ اﻟﻌﻨﺎﺻﺮ واﻟﻤﻤﻴﺰات اﻟﻲ ﺗﺤﺪد ﺷﻜﻞ وﺳﻠﻮك اﻟﻌﻨﺼﺮ ﻓﻲ ﺷﺎﺷﺔ اﻟﺘﻄﺒﻴﻖ‪.‬‬
‫‪Attribute Name Namespace Prefix‬‬ ‫"‪android:text = "Hello‬‬ ‫‪Attribute Value‬‬
‫ﻣﺴﺎﺣﺔاﻹﺳـــــﻢ اﺳــــﻢاﻟﻤــﻴﺰة‬ ‫ﻗﻴــﻤﺔ اﻟﻤــﻴﺰة‬
‫ﻳﻮﺟﺪ ﻓﻲ آﺧﺮ ﻫﺬا اﻟﻤﻠﺨﺺ ﺟﺪول ﻳﻀﻢ ﻗﺎﺋﻤﺔ أﻏﻠﺐ اﻟﻤﻤﻴﺰات اﻟﻤﺴﺘﺨﺪﻣﺔ ﻓﻲ ﻫﺬه اﻟﺪورة ووﻇﻴﻔﺘﻬﺎ‬
‫‪2‬‬
‫‪Font Sizes and Colors‬‬ ‫ﺣﺠﻢ اﻟﺨﻄﻮط واﻷﻟﻮان‬
‫ﻗﺎﻣﺖ ﺟﻮﺟﻞ ﺑﻌﻤﻞ ﻣﻮﻗﻊ ‪ Material Design‬وﺣﺪدت ﻓﻴﻪ أﺣﺠﺎم اﻟﺨﻄﻮط واﻷﻟﻮان وﻏﻴﺮﻫﺎ ﻣﻦ اﻟﺨﺼﺎﺋﺺ ﺑﺤﻴﺚ ﻳﺴﺘﻄﻴﻊ‬
‫اﻟﻤﻄﻮر ﺑﺎﺳﺘﺨﺪﻣﻬﺎ ﺗﺼﻤﻴﻢ ﺗﻄﺒﻴﻘﺎت ﻣﺘﻨﺎﺳﻘﺔ وﺑﺠﻮدة ﻋﺎﻟﻴﺔ‪ .‬ﻓﺤﺪدت ﻣﺜﻼ ﻟﻠﻌﻨﻮاﻧﻴﻦ ﺣﺠﻢ ﺧﻂ ﻣﻌﻴﻦ وﻟﻨﺼﻮص‬
‫اﻷزرار ﺗﻨﺴﻴﻖ ﻣﻌﻴﻦ‪ .‬وﻳﻤﻜﻦ اﻟﺮﺟﻮع ﻟﻬﺬه اﻟﺘﻔﺎﺻﻴﻞ ﻣﻦ ﺧﻼل اﻟﻤﻮﻗﻊ ‪https://material.io/guidelines/#‬‬

‫‪ImageView‬‬ ‫ﻋﻨﺼﺮ ﻋﺮض اﻟﺼﻮر‬

‫‪<ImageView‬‬
‫وﻫﻮ ﻋﻨﺼﺮ ﻳﺴﺘﺨﺪم ﻟﻌﺮض اﻟﺼﻮر واﻟﺮﺳﻮﻣﺎت ﻓﻲ ﺷﺎﺷﺔ اﻟﺘﻄﺒﻴﻖ‪,‬‬
‫"‪android:src="@drawable/cake‬‬ ‫ﻋﻨﺪﻣﺎ ﻳﻜﻮن ﻋﺮض اﻟﺼﻮرة ﻳﻐﻄﻲ ﻛﺎﻣﻞ اﻟﻤﺴﺎﺣﺔ ﻟﻌﺮض ﺷﺎﺷﺔ‬
‫"‪android:layout_width="wrap_content‬‬
‫"‪android:layout_height="wrap_content‬‬ ‫اﻟﺠﻬﺎز وﺑﺪوت ﻫﻮاﻣﺶ ﻓﺈن اﻟﺼﻮرة ﺗﺴﻤﻰ ‪Full Bleeding Image‬‬
‫>‪android:scaleType="center" /‬‬

‫ﻣﺜﺎل ﻛﻮد‪ImageView‬‬
‫اﻟﻤﻌﻨـــﻰ‬ ‫اﻟﻤﻤﻴــﺰات‬
‫وﻫﻨﺎ ﻳﺤﺪد ﻣﺼﺪر اﻟﺼﻮرة ﻣﻦ دون ذﻛﺮ اﻣﺘﺪادﻫﺎ ﻓﻬﺬه اﻟﺼﻮرة ﻓﻲ اﻟﻤﺜﺎل أﻋﻼه ﻣﻮﺟﻮدة ﻓﻲ اﻟﻤﺴﺎر ‪drawable‬‬ ‫‪android:src‬‬
‫ﺗﺴﺘﺨﺪم ﻟﺘﺤﺠﻴﻢ اﻟﺼﻮرة داﺧﻞ ﺷﺎﺷﺔ اﻟﺘﻄﺒﻴﻖ ﺑﻄﺮق ﻣﺨﺘﻠﻔﺔ‬
‫”‪ - “center‬ﻟﻌﺮض اﻟﺼﻮرة ﻓﻲ اﻟﻮﺳﻂ ﻣﻦ دون ﺗﺤﺠﻴﻢ‬ ‫‪android:scaleType‬‬
‫”‪ - “centerCrop‬ﻟﺘﺤﺠﻴﻢ اﻟﺼﻮرة ﺑﺸﻜﻞ ﻣﺘﻨﺎﺳﻖ ﺑﺤﻴﺚ ﺗﻜﻮن ﺗﺴﺎوي أﺑﻌﺎد ﺷﺎﺷﺔ اﻟﺘﻄﺒﻴﻖ ﻧﺎﻗﺼﺎ اﻟﻬﻮاﻣﺶ‬
‫ﺟﺪول ﻟﺒﻌﺾ ﻣﻤﻴﺰات ‪ImageView‬‬

‫‪View Group‬‬ ‫ﻋﺮض اﻟﺘﺨﻄﻴﻂ‬

‫ﻳﺴﺘﺨﺪم ﻛﺈﻃﺎر ﻣﺤﺘﻮى ﻟﻌﺪة ﻋﻨﺎﺻﺮ ﺑﺪاﺧﻠﻪ وﻳﻤﻜـــﻦ اﻟﺘﺤﻜﻢ ﻓﻲ أﺑﻌﺎده وﺧﺼﺎﺋﺼﻪ‪ .‬ﻳﻄﻠﻖ‬
‫ﻋﻠﻰ ﻫﺬا اﻹﻃﺎر اﺳﻢ أب ‪ Parent‬وﻳﻄﻠﻖ ﻋﻠﻰ اﻟﻌﻨﺎﺻﺮ اﻟﺘﻲ ﺑﺪاﺧﻠﻪ أﺑﻨﺎء ‪ Childs‬وﻳﺴﻤﻰ اﻷﺑﻨﺎء‬
‫أﻳﻀﺎ إﺧـــﻮة ‪ Siblings‬وﻛﺄﻧﻤﺎ اﻷب ﻳﺤﻤﻞ اﻷﺑﻨﺎء ﺑﺪاﺧﻠﻪ‪ ،‬ﻳﺠﺐ ﻛﺬﻟﻚ ﻣﻼﺣﻈﺔ‬
‫وﺟﻮد أب رﺋﻴﺴﻲ واﺣﺪ ﻓﻘﻂ وﻳﻤﻜﻦ أن ﻳﺤﺘﻮي ﺑﺪاﺧﻠﻪ ﻋﻠﻰ آﺑﺎء وأﺑﻨﺎء آﺧﺮﻳﻦ‬

‫‪Linear Layout‬‬ ‫اﻟﺘﺨﻄﻴﻂ اﻟﺨﻄﻲ‬

‫ﻫﻮ ﺗﺨﻄﻴﻂ ﺧﻄﻲ ﻣﻦ ﻧﻮع ‪ ViewGroup‬ﻳﺴﺘﺨﺪم ﻟﺘﺮﺗﻴﺐ اﻟﻌﻨﺎﺻﺮ ﺑﺪاﺧﻠﻪ‬


‫ﻋﻠﻰ ﺷﻜﻞ أﻋﻤﺪة أو ﺻﻔﻮف‪ .‬وﻣﻦ ﺧﻼل ﻛﻮدات اﻟـ ‪ XML‬ﻳﻤﻜﻦ اﺧﺘﻴﺎر ‪Childs‬‬
‫ﻃﺮﻳﻘﺔ ﻋﺮض اﻟﻌﻨﺎﺻﺮ ﺑﺎﺳﺘﺨﺪام اﻟﻤﻴﺰة ‪orientation‬‬

‫‪3‬‬
‫ﻣﺜﺎل ﺗﻮﺿﻴﺤﻲ ﻟﻠﺘﺨﻄﻴﻂ اﻟﺨﻄﻲ‬
‫ﺑﺎﻟﻨﺴﺒﺔ ﻟﻬﺬه اﻟﻤﻴﺰة‬
‫ﻧﺴﺘﻌﻤﻞ ﻣﺴﺎﺣﺔ اﻻﺳﻢ ﻫﺬه ﻟﻜﻲ ﻧﺤﺪد أن‬
‫ﻛﻞ ﻫﺬه اﻟﻤﻤﻴﺰات ﺗﻨﺘﻤﻲ إﻟﻰ أﻧﺪروﻳﺪ ﻟﺬﻟﻚ‬
‫ وﻧﺴﺘﻄﻴـﻊ أن‬android: ‫ﺗﺒﺪأ ﺟﻤﻴﻌﻬــﺎ ﺑﻜﻠﻤـﺔ‬
‫ﻧﻌﻤﻞ ﻣﺴﺎﺣﺔ اﺳﻢ ﺧﺎﺻﺔ ﺑﻨﺎ وﻋﻤﻞ ﻣﺮﺟﻊ‬
Prefix or alias ‫ وﺗﺴﻤﻰ أﻳﻀﺎ‬.‫اﻟﻤﻮﻗﻊ ﻟﻬـﺎ‬

‫ﻟﻤﻌﻠﻮﻣﺎت أﻛﺜﺮ ﺣﻮل اﻟﻤﻮﺿﻮع ﻳﺮﺟﻰ ﻣﺮاﺟﻌﺔ‬


‫ﺷﺮوﺣﺎت اﻷﺳﺘﺎذ ﺣﺴﻦ ﻳﻮﺳﻒ‬

layout_height layout_width ‫اﻟﻘﻴﻢ اﻟﺘﻲ ﻳﻘﺒﻠﻬﺎ ﻃﻮل وﻋﺮض اﻟﺘﺨﻄﻴﻂ‬


‫ﺣﺠﻢ ﺛﺎﺑﺖ ﻟﻠﻄﻮل واﻟﻌﺮض‬ Fixed dp
‫ إﺣﺘﻮاء اﻟﻤﺤﺘﻮى ﺿﻤﻦ اﻟﺘﺨﻄﻴﻂ‬wrap_content
‫ ﻃﻮل وﻋﺮض ﻟﻺﺑﻦ ﻣﺴﺎوي اﻟﻄﻮل واﻟﻌﺮض ﻟﻸب‬match_parent

layout_weight ‫وزن اﻟﺘﺨﻄﻴﻂ‬


‫وﻫﻲ ﻧﺴﺒﺔ ﺗﺤﺴﺐ ﺑﻌﺪد ﺻﺤﻴﺢ ﺗﻌﻄﻲ ﻃﻮﻻ وﻋﺮﺿﺎ ﻟﻠﻌﻨﺼﺮ ﻓﻲ اﻟﺘﻄﺒﻴﻖ ﺑﺸﻜﻞ ﻣﻮزون ﻣﻘﺎرﻧﺔ‬
‫ﺑﺎﻟﻌﻨﺎﺻﺮ اﻷﺧﺮى اﻷﺑﻨﺎء ﻛﻠﻤﺎ زادت ﻧﺴﺒﺔ اﻟﻮزن ﻟﻠﻌﻨﺼﺮ ﻛﻠﻤﺎ زادت اﻟﻤﺴﺎﺣﺔ اﻟﺘﻲ ﻳﻐﻄﻴﻬﺎ ﻓﻲ اﻟﺸﺎﺷﺔ‬
‫واﻟﻘﻴﻤﺔ اﻹﻓﺘﺮاﺿﻴﺔ ﻟﻬﺎ ﻫﻲ ﺻﻔﺮ وﻫﻮ ﺗﻤﺜﻴﻞ ﻣﺴﺎﺣﺔ اﻟﻌﻨﺼﺮ ﻃﻮﻻ او ﻋﺮﺿﺎ ﺑﻨﺴﺒﺔ ﻣﻌﻴﻨﺔ ﻣﻦ اﻟﺸﺎﺷﺔ‬
LinearLayout ‫او اﻟﻌﻨﺼﺮ اﻻب وﻫﺬه اﻟﻤﻴﺰة او اﻟﺨﺼﻴﺼﺔ ﺧﺎﺻﺔ ﻓﻘﻂ ﺑﺎﻟـ‬

<LinearLayout
‫ﻣﺜﺎل ﺗﻮﺿﻴﺤﻲ ﻟﻮزن اﻟﺘﺨﻄﻴﻂ‬
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ImageView
android:src="@drawable/ocean"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:scaleType="centerCrop" /> <TextView
android:text="Bonfire at the beach"
<TextView android:layout_width="match_parent"
android:text="You're invited!" android:layout_height="wrap_content"
android:layout_width="match_parent" android:textColor="@android:color/white"
android:layout_height="wrap_content" android:layout_weight="0"
android:textColor="@android:color/white" android:textSize="34sp"
android:textSize="54sp" android:background="#009688" />
android:layout_weight="0"
android:background="#009688" /> </LinearLayout>

4
‫ﺷﺮح اﻟﻜﻮد اﻟﺴﺎﺑﻖ‬
‫اﻟـــﻮزن‬ ‫اﻟﻄـــﻮل‬ ‫اﻟﻌــﺮض‬ ‫اﻟﻌﻨﺎﺻـﺮ‬ ‫ﻣﻦ اﻟﻤﺜﺎل اﻟﺴﺎﺑﻖ ﻧﺮﻛﺰ ﻓﻘﻂ ﻋﻠﻰ‬
‫‪1‬‬ ‫‪0dp‬‬ ‫‪match_parent‬‬ ‫‪ImageView‬‬ ‫ﻃﻮل وﻋﺮض ووزن اﻟﻌﻨﺎﺻﺮ اﻷﺑﻨﺎء واﻟﺘﻲ‬
‫‪0‬‬ ‫‪wrap_content‬‬ ‫‪match_parent‬‬ ‫‪TextView‬‬
‫ﻫﻲ ﺛﻼث ﻋﻨﺎﺻﺮ وﻧﻘﺎرن ﻛﻞ ﻗﻴﻤﺔ ﻓﻴﻬﺎ‬
‫ﻟﺘﺘﻀﺢ ﻓﺎﺋﺪة وزن اﻟﻌﻨﺎﺻﺮ‬
‫‪0‬‬ ‫‪wrap_content‬‬ ‫‪match_parent‬‬ ‫‪TextView‬‬

‫ﻳﺘﺒﻴﻦ أن اﻟﻌﻨﺼﺮ اﻟﺜﺎﻧﻲ واﻟﺜﺎﻟﺚ ﻛﺎﻧﺖ ﻗﻴﻤﺔ اﻟﻮزن ﻫﻲ ﺻﻔﺮ واﻟﻄﻮل ﻛﺎن ﺑﺎﺣﺘﻮاء اﻟﻨﺺ ﻓﻼ ﺣﺎﺟﺔ ﻹﻋﻄﺎء ﻗﻴﻤﺔ‬
‫ﺻﻔﺮ ﻟﻠﻄﻮل ﻓﻤﺎ ﻧﺮﻳﺪه ﻓﻘﻂ ﻫﻮ أن ﻳﺘﻢ اﺣﺘﻮاء اﻟﻨﺺ وﻳﻜﻮن ﻇﺎﻫﺮا ﻟﻠﻤﺴﺘﺨﺪم‬
‫أﻣﺎ ﻗﻴﻤﺔ ﻋﻨﺼﺮ اﻟﺼﻮرة ﻓﻘﺪ ﺟﻌﻠﻨﺎ اﻟﻄﻮل ﺻﻔﺮ ﺣﺘﻰ ﻧﻌﻄﻲ اﻟﻤﺠﺎل ﻟﻘﻴﻤﺔ اﻟﻮزن ﻓﻲ اﻟﺘﺤﻜﻢ ﻓﻲ اﻟﻄﻮل‪،‬‬
‫وﻛﺎﻧﺖ ﻗﻴﻤﺔ اﻟﻮزن ﻫﻲ ‪ 1‬وذﻟﻚ ﻷن اﻟﻌﻨﺎﺻﺮ اﻷﺧﺮى ﻗﻴﻤﺘﻬﺎ ﺻﻔﺮ وﻟﻦ ﺗﺄﺛﺮ اﻟﻘﻴﻤﺔ ﻫﻨﺎ ﺣﺘﻰ ﻟﻮ ﺟﻌﻠﺘﻬﺎ ‪ 10‬ﻟﻜﻦ‬
‫ﻟﻮ أردﻧﺎ ﻣﺜﻼ ﺗﻮزﻳﻊ اﻷوزان ﻋﻠﻰ ﺛﻼﺛﺔ ﻋﻨﺎﺻﺮ ﺑﺎﻟﺘﺴﺎوي ﻓﺈن ﻛﻞ ﻋﻨﺼﺮ ﺳﻴﻜﻮن وزﻧﻪ ‪ 1‬وﺳﻴﺄﺧﺬ ﻛﻞ ﻋﻨﺼﺮ ﻧﺴﺒﺔ‬
‫اﻟﺜﻠﺚ ﻣﻦ ﻃﻮل اﻟﺸﺎﺷﺔ‬

‫ﺑﺎﻟﻨﺴﺒﺔ ﻋﻦ ﻋﺮض اﻟﻌﻨﺎﺻﺮ ﻓﻜﻤﺎ ﻫﻮ واﺿﺢ أن ﻛﻞ اﻟﻌﻨﺎﺻﺮ ﻃﻮﻟﻬﺎ ﻳﺴﺎوي ﻃﻮل اﻟﺘﺨﻄﻴﻂ اﻷب‬

‫‪Relative Layout‬‬

‫وﻫﻮ ﺗﺨﻄﻴﻂ ﻧﺴﺒﻲ ﻣﻦ ﻧﻮع ‪ ViewGroup‬ﻳﻘـﻮم ﺑﺘﺮﺗﻴــﺐ اﻟﻌﻨﺎﺻﺮ ﺑﺪاﺧﻠﻪ‬


‫ﺑﺎﻟﻨﺴﺒﺔ إﻟﻰ أﺑﻌﺎد اﻟﺘﺨﻄﻴﻂ اﻷب أو ﻧﺴﺒﺔ إﻟﻰ أﺑﻌﺎد اﻷﺑﻨﺎء أو اﻷﺧﻮة‬
‫اﻵﺧﺮﻳﻦ ﻓﻲ داﺧﻞ اﻟﺘﺨﻄﻴﻂ‪ ،‬ﻓﻲ اﻟﺸﻜﻞ أدﻧﺎه ﻳﺒﻴﻦ ﻋﻨﺎﺻﺮ أﺑﻨﺎء ﻣﻮزﻋﺔ‬
‫داﺧﻞ ﺗﺨﻄﻴﻂ ﻧﺴﺒﻲ أب وﻳﺒﻴﻦ اﻟﻤﺤﺎذاة ﻟﻜﻞ ﻋﻨﺼﺮ ﻧﺴﺒﺔ إﻟﻰ اﻵﺧﺮ‪.‬‬

‫‪android:id‬‬ ‫ﻣﻴﺰة اﻻﺳﻢ اﻟﻤﻌﺮف‬


‫ﺗﺴﺘﺨﺪم ﻫﺬه اﻟﻤﻴﺰة ﻹﻋﻄﺎء اﺳﻢ ﻣﻌﺮف ﻟﻠﻌﻨﺼﺮ ﻓﻲ اﻟﺘﻄﺒﻴﻖ ﺑﺤﻴﺚ ﻳﻜﻮن اﺳﻢ ﻣﺮﺟﻊ ﻳﻤﻜﻦ اﻹﺷﺎرة إﻟﻴﻪ ﻓﻲ ﻣﻜﺎن‬
‫آﺧﺮ ﻓﻲ ﻛﻮد اﻟﺒﺮﻣﺠﺔ ﺳﻮاء ﻓﻲ اﻟـ ‪ XML‬أو ﻓﻲ أﻛﻮاد اﻟﺒﺮﻣﺠﺔ ‪Java‬‬
‫ﻹﻋﻄﺎء ﻗﻴﻤﺔ ﻟﻼﺳﻢ اﻟﻤﻌﺮف ﻷول ﻣﺮة ﻳﺠﺐ وﺿﻊ ﻋﻼﻣﺔ ‪ +‬ﻓﻲ اﻟﻘﻴﻤﺔ اﻟﻤﻴﺰة ﻛﻤﺎ ﻫﻮ ﻣﻮﺿﺢ ﻫﻨﺎ‬
‫"‪ android:id="@+id/lyla_text_view‬وﻳﺠﺐ أن ﻻ ﻳﺒﺪأ اﻻﺳﻢ ﺑﺮﻗﻢ‬

‫‪.......... android:layout_toLeftOf‬‬ ‫‪android:layout_align‬‬ ‫ﻣﺤﺎذاة اﻟﻌﻨﺎﺻﺮ‬


‫وﻫﻲ ﻣﻴﺰة ﺗﻘﻮم ﺑﻤﺤﺎذاة اﻟﻌﻨﺎﺻﺮ داﺧﻞ اﻟﺘﺨﻄﻴﻂ ﺑﺎﻟﻨﺴﺒﺔ ﻟﻠﺘﺨﻄﻴﻂ اﻷب أو ﺑﺎﻟﻨﺴﺒﺔ ﻟﻸﺑﻨﺎء اﻵﺧﺮﻳﻦ ﻓﻲ ﻧﻔﺲ‬
‫اﻟﺘﺨﻄﻴﻂ وﻫﻲ ﻣﻴﺰة ﻣﺮﺗﺒﻄﺔ ﺑﺨﺼﺎﺋﺺ اﻟﺘﺨﻄﻴﻂ ‪ViewGroup‬وﻳﻤﻜﻦ ﺗﺤﺪﻳﺪ ﻧﻮع ﻣﺤﺎذاة اﻟﻌﻨﺼﺮ وﻳﺄﺗﻲ اﻵن ﻣﺜﺎل ﺗﻢ‬
‫اﺳﺘﺨﺪام أﻧﻮاع ﻣﺤﺎذاة ﻣﺨﺘﻠﻔﺔ ﻓﻴﻪ ﺳﻴﺘﻢ ﺷﺮﺣﻬﺎ ﻓﻲ ﺑﺎﻟﺘﻔﺼﻴﻞ ﺑﻌﺪ ذﻟﻚ‬
‫إذا ﻟﻢ ﻳﺘﻢ ﺗﺤﺪﻳﺪ ﻣﺤﺎذاة ﻟﻠﻌﻨﺼﺮ ﺳﻴﻀﻌﻪ اﻟﺘﺨﻄﻴﻂ ﻓﻲ اﻟﺰاوﻳﺔ اﻟﻌﻠﻴﺎ اﻟﻴﺴﺮى ﻟﻠﺘﻄﺒﻴﻖ‬

‫‪5‬‬
‫ﻣﺜﺎل ﺗﻮﺿﻴﺤﻲ ﻟﻠﺘﺨﻄﻴﻂ اﻟﻨﺴﺒﻲ‬
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/lyla_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:textSize="24sp"
android:text="Lyla" />

<TextView
android:id="@+id/me_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@id/lyla_text_view"
android:textSize="24sp"
android:text="Me" />

<TextView
android:id="@+id/natalie_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_above="@id/lyla_text_view"
android:textSize="24sp"
android:text="Natalie" />

<TextView
android:id="@+id/jennie_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:textSize="24sp"
android:text="Jennie" />

<TextView
android:id="@+id/omoju_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_above="@id/jennie_text_view"
android:textSize="24sp"
android:text="Omoju" />
<TextView
<TextView android:id="@+id/kunal_text_view"
android:id="@+id/amy_text_view" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_alignParentTop="true"
android:layout_alignParentRight="true" android:layout_toLeftOf="@id/ben_text_view"
android:layout_above="@id/omoju_text_view" android:textSize="24sp"
android:textSize="24sp" android:text="Kunal" />
android:text="Amy" />
.......... <TextView
<TextView android:id="@+id/kagure_text_view"
android:id="@+id/ben_text_view" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_alignParentTop="true"
android:layout_alignParentTop="true" android:layout_toRightOf="@id/ben_text_view"
android:layout_centerHorizontal="true" android:textSize="24sp"
android:textSize="24sp" android:text="Kagure" />
android:text="Ben" />
</RelativeLayout>

6
‫ﺷﺮح اﻟﻜﻮد اﻟﺴﺎﺑﻖ‬

‫ ﻧﻘﺎرن ﻗﻴﻢ اﻟﻤﺤﺎذاة ﻟﻜﻞ ﻣﻨﻬﺎ‬TextView ‫ أﺷﺨﺎص ﻣﻀﻤﻨﺔ ﻓﻲ ﻋﻨﺎﺻﺮ ﻣﻦ ﻧﻮع‬9 ‫ﻓﻲ اﻟﻤﺜﺎل اﻟﺴﺎﺑﻖ ﻛﺎن ﻫﻨﺎك أﺳﻤﺎء‬

٢- ‫اﻟﻤﺤﺎذاة‬ ١- ‫اﻟﻤﺤﺎذاة‬ ‫اﺳﻢ اﻟﺸﺨﺺ‬


layout_alignParentLeft = "true" layout_alignParentBottom = "true" Lyla
layout_toRightOf = "@id/lyla_text_view" layout_alignParentBottom = "true" Me
layout_above = "@id/lyla_text_view" layout_alignParentLeft = "true" Natalie
layout_alignParentRight = "true" layout_alignParentBottom = "true" Jennie
layout_above = "@id/jennie_text_view" layout_alignParentRight = "true" Omoju
layout_above = "@id/omoju_text_view" layout_alignParentRight = "true" Amy
layout_centerHorizontal = "true" layout_alignParentTop = "true" Ben
layout_toLeftOf = "@id/ben_text_view" layout_alignParentTop = "true" Kunal
layout_toRightOf = "@id/ben_text_view" layout_alignParentTop = "true" Kagure

‫ﻟﻴﻠﻰ وﺟﻴﻨﻲ وﺑﻦ ﻫﻢ اﻷﺷﺨﺎص اﻷﺳﺎﺳﻴﻴﻦ اﻟﺬﻳﻦ ﺳﺘﻌﺘﻤﺪ اﻟﻤﺤﺎذاة ﻟﻸﺷﺨﺎص اﻵﺧﺮﻳﻦ ﺑﺎﻟﻨﺴﺒﺔ ﻟﻬﻢ‬
‫" ﻟﻠﻴﻠﻰ ﻓﺈﻧﻨﺎ ﻧﻘﺼﺪ ﻣﺤﺎذاﺗﻬﺎ ﻟﻠﺠﺎﻧﺐ‬true" ‫ ﺑﻘﻴﻤﺔ‬layout_alignParentBottom ‫ﻋﻨﺪﻣﺎ ﻧﺤﺪد اﻟﻤﺤﺎذاة‬
layout_alignParentRight ‫ ﻓﺘﺼﺒﺢ‬Right ‫اﻟﺴﻔﻠﻲ ﻟﻠﺘﺨﻄﻴﻂ اﻷب وﻋﻨﺪﻣﺎ ﻧﺮﻳﺪ اﻟﻤﺤﺎذاة ﻟﻠﻴﻤﻴـﻦ ﻧﻐﻴﺮ اﻟـﻰ‬
Amy ‫" ﻛﻤﺎ ﻫﻮ اﻟﺤﺎل ﻟـ‬true" ‫ﺑﻘﻴﻤﺔ‬

‫ﻓﻲ اﻟﻤﺜﺎل أﻋﻼه ﺗﻢ اﺳﺘﺨﺪام ﻣﻴﺰة اﻻﺳﻢ اﻟﻤﻌﺮف ﻛﻤﺮﺟﻊ ﻟﻴﻜﻮن اﻟﺸﺨﺺ ﻓﻲ ﻣﺤﺎذاة اﻟﺸﺨﺺ اﻟﻤﺸﺎر‬
‫ ﻓﺈﻧﻪ ﻳﻘﻊ‬Omoju ‫ وذﻟﻚ ﻟﻠﺸﺨﺺ‬layout_above = "@id/jennie_text_view" ‫إﻟﻴﻪ ﻓﻲ ﻣﻴﺰة اﻟﻤﺤﺎذاة ﻣﺜﻞ‬
.‫ ﻋﻨﺪ اﺳﺘﺨﺪام ﻣﻴﺰة اﻻﺳﻢ اﻟﻤﻌﺮف ﻛﻤﺮﺟﻊ‬+ ‫ وﻳﻼﺣﻆ ﻛﺬﻟﻚ ﻋﺪم وﺟﻮد ﻋﻼﻣﺔ‬Jennie ‫ﻓﻮق‬

Paddings & Margins

‫ ﻫﻲ ﻣﻤﻴﺰات ﺗﻘﻮم ﺑﻌﻤﻞ ﻣﺴﺎﺣﺔ ﺣﻮل‬Margins ‫اﻟﻬﻮاﻣﺶ‬


‫اﻟﻌﻨﺼﺮ ﺧﺎرج ﺣﺪود اﻹﻃﺎر ﻟﻠﻌﻨﺼﺮ‬
‫ ﻫﻲ ﻣﻤﻴﺰات ﺗﻘﻮم ﺑﻌﻤﻞ ﻣﺴﺎﺣﺔ ﺣﻮل‬Paddings ‫ﺣﺸـــــﻮ‬
‫اﻟﻌﻨﺼﺮ داﺧﻞ ﺣﺪود اﻹﻃﺎر ﻟﻠﻌﻨﺼﺮ‬

<ImageView ‫ ﺑﻌﻤﻞ اﻟﻤﺴﺎﺣﺔ داﺧﻞ إﻃﺎر اﻟﻌﻨﺼﺮ ﻓﻔﻲ‬Paddings ‫ﺗﻘﻮم اﻟﻤﻴﺰة‬


android:paddingTop="16dp" ‫اﻟﻤﺜﺎل ﻋﻠﻰ اﻟﻴﺴﺎر ﺗﻢ اﺳﺘﺨﺪام ﻣﻴﺰة اﻟﺤﺸﻮ ﻹﻋﻄﺎء اﻟﻤﺴﺎﺣﺎة‬
android:paddingBottom="8dp"
android::paddingLeft="16dp"
‫ ﺣﻮل اﻟﻌﻨﺼﺮ ﺑﺈﺳﺘﺨﺪام اﻟﻤﻤﻴﺰات‬16dp ‫ أو‬8dp ‫ﺑﻤﻘﺪار‬
android::paddingRight="16dp" />
android:paddingTop android:paddingLeft
android:paddingBottom android:paddingRight

7
‫ﺧﻄﻮات ﺗﺼﻤﻴﻢ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ‬
‫اﻟﻤﺜﺎل ﻫﺬه اﻟﻤﺮﺣﻠﺔ ﺑﺘﻮزع‬
‫ﻧﻘﻮم ﻓﻲ‬ ‫ﺑﻌﻤﻞﻧﻘﻮم ﺑﺮﺳﻢ‬
‫اﻟﻤﺴﺎﺣﺔ داﺧﻞ إﻃﺎر اﻟﻌﻨﺼﺮ ﻓﻔﻲ‬ ‫اﻟﺘﺼﻤﻴﻢ‬ ‫ﻣﺮﺣﻠﺔ‬
‫اﻟﻤﻴﺰة‬ ‫ﻓﻲ‬
‫ﺗﻘﻮم‬

‫ﺗﺼﻤﻴﻢ‬
‫ﺗﺮﺗﻴــﺐ‬
‫اﻟﻌﻨﺎﺻﺮ ﻓﻲ ﺷﺎﺷﺔ اﻟﺘﻄﺒﻴﻖ‬ ‫اﻟﻔﻜﺮة وإﻋﻄﺎء ﻓﻜﺮة ﻋﺎﻣﺔ ﻋﻦ‬
‫ﺑﻤﻘﺪار‬
‫وﺗﺤﺪﻳﺪ اﻟﻤﻤﻴﺰات اﻟﺘﻲ ﺗﺨﺺ‬ ‫اﻟﻤﺴﺎﺣﺎة‬ ‫ﻹﻋﻄﺎء‬ ‫اﻟﺤﺸﻮ‬ ‫اﺳﺘﺨﺪام ﻣﻴﺰة‬
‫اﻟﺘﻄﺒﻴﻖ‬ ‫اﻟﺴﺎﺑﻖ ﺗﻢ‬
‫ﺳﺘﻈﻬﺮ واﺟﻬﺔ‬ ‫ﻛﻴﻒ‬
‫اﻟﻤﺤﺎذاة وﻣﺎ إﻟﻰ ذﻟﻚ‬ ‫ﺑﺈﺳﺘﺨﺪاماﻟﻌﻨﺎﺻﺮ‬
‫اﻟﻤﻴﺰات‬ ‫اﻟﻌﻨﺼﺮ ﻣﺎﻫﻲ‬
‫ﻟﻠﻤﺴﺘﺨﺪﻣﻴﻦ‬
‫ﺣﻮل‬
‫اﻟﺘﻲ ﺳﻨﺤﺘﺎﺟﻬﺎ ﻟﻬﺬه اﻟﻮاﺟﻬﺔ‬

‫ﻓﻲ ﻫﺬه اﻟﻤﺮﺣﻠﺔ ﻧﻘﻮم ﺑﺘﻨﺴﻴﻖ اﻟﻌﻨﺎﺻﺮ ﻣﺜﻞ ﺗﻐﻴﺮ ﻟﻮن وﺣﺠﻢ وﻧﻮع اﻟﺨﻄﻮط وأﻟﻮان اﻟﺨﻠﻔﻴﺔ‬

‫ﺗﻨﺴﻴﻖ‬
‫واﻟﻬﻮاﻣﺶ واﻟﺤﺸﻮ وﺗﻌﺪﻳﻞ اﻟﺨﺼﺎﺋﺺ ﻟﺘﺤﺠﻴﻢ اﻟﺼﻮر ﻹﻋﻄﺎء اﻟﺘﻄﺒﻴﻖ ﻣﻈﻬﺮا ﺟﺬاﺑﺎ ﻣﺎ‬
‫ﻳﺴﺎﻋﺪ ﺗﻔﻀﻴﻞ اﻟﺘﻄﺒﻴﻖ ﻣﻦ اﻟﻤﺴﺘﺨﺪﻣﻴﻦ وﺣﺼﻮﻟﻪ ﻋﻠﻰ إﻧﺘﺸﺎر ﺑﺸﻜﻞ أﻓﻀﻞ‬

‫‪LinearLayout‬‬
‫‪RelativeLayout‬‬ ‫اﺧﺘﺒﺮ ﻧﻔﺴﻚ ﺗﺨﻄﻴﻂ ﻧﺴﺒﻲ أم ﺧﻄﻲ ؟ ‪LinearView‬‬
‫ﻗﻢ ﺑﺘﺤﺪﻳﺪ ﻧﻮع اﻟﺘﺨﻄﻴﻂ وﺣﺎول ﻣﻌﺮﻓﺔ أﻧﻮاع اﻟﻌﻨﺎﺻﺮ‬

‫‪LinearView‬‬
‫‪1 ImageView, 3 TextView‬‬

‫‪8‬‬
<TextView t1 t2 t3 t4 ‫اﻟﺘﺨﻄﻴﻂ‬ ‫ﺧﻼل‬ ‫ﻣﻦ‬
android:layout_width="wrap_content"
android:layout_height="wrap_content" ‫ﻓﻲ‬ ‫اﻟﺬي‬ ‫اﻟﻨﺴﺒﻲ‬
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" ‫ ﺣﺪد اﻻﺳﻢ‬،‫اﻟﻮﺳﻂ‬
android:id="@+id/t1" /> ‫اﻟﻤﻌﺮف ﻟﻜﻞ ﻣﺮﺑﻊ ﻧﺺ‬
t5 t6 t7
‫ﻛﻤﺎ ﻓﻲ اﻟﻤﺜﺎل‬
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content" ‫ﻧﻼﺣﻆ ﻓﻲ اﻟﺘﺨﻄﻴﻂ اﻟﻨﺴﺒﻲ‬
android:layout_alignParentTop="true"
‫ﻣﻤﻴﺰات ﻟﻠﻤﺤﺎذاة ﻓﻲ اﻟﻌﻨﺎﺻﺮ‬
android:layout_toLeftOf="@id/t3"
/> ‫إﻣﻜﺎﻧﻴﺔﺗﺮاﻛﺐاﻟﻌﻨﺎﺻﺮﻋﻠﻰﺑﻌﻀﻬﺎ‬
t8 t9 t10 t11

<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentTop="true"
android:layout_centerVertical="true" android:layout_centerHorizontal="true"
/> />

<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentRight="true" android:layout_alignParentTop="true"
android:layout_centerVertical="true" android:layout_alignParentRight="true"
/> />

<TextView <TextView
android:id="@+id/t9" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_centerVertical="true"
android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"
android:layout_toRightof="@id/t8"
/>
/>

<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentBottom="true"
android:layout_toLeftOf="@id/t3" android:layout_alignParentLeft="true"
/> />

<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentBttom="true"
android:layout_alignParentRight="true" android:layout_centerHorizontal="true"
/> />

9
Constraint Layout ‫ﻣﻨﺎﻗﺸﺔ ﺣﻮل أداة‬
‫اﻷداة اﻟﺘﻲ ﺗﺠﻌﻞ إﻧﺸﺎء واﺟﻬﺎت اﻟﻤﺴﺘﺨﺪم اﻟﻤﺴﺘﺠﻴﺒﺔ ﺳﺮﻳﻊ ﻟﻠﻐﺎﻳﺔ ﻣﻊ اﻟﻌﺪﻳﺪ ﻣﻦ أﻧﻮاع اﻟﻤﻜﻮﻧــــــﺎت اﻟﻤﺨﺘﻠﻔﺔ‬
‫ ﻓﻲ اﻟﺪورة ﺑﺪﻻ ﻋﻨﻬﺎ وﻟﻤﻌﺮﻓﺔ اﻟﻔﺮق ﻧﺠﺪ اﻟﻤﻘﺎرﻧﺔ ﻓﻲ اﻷﺳﻔـﻞ‬RelativeLayout - LinearLayout ‫ﻟﻜﻦ ﺗﻢ اﺳﺘﺨﺪام‬

Constraint Layout ‫ﻣﺜﺎل ﻋﻠﻰ أﻛﻮاد ﺑﺎﺳﺘﺨﺪام‬


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.udacity.myapplication.MainActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintLeft_toLeftOf="@+id/activity_main"
app:layout_constraintTop_toTopOf="@+id/activity_main"
app:layout_constraintRight_toRightOf="@+id/activity_main"
app:layout_constraintBottom_toBottomOf="@+id/activity_main" />

</android.support.constraint.ConstraintLayout>

Constraint Layout ‫ﻣﺜﺎل ﻋﻠﻰ أﻛﻮاد ﺑﺪون اﺳﺘﺨﺪام‬


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="8dp"
tools:context="com.udacity.myapplication.MainActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</RelativeLayout>

10
‫ﻛﻴﻒ ﺗﺨﺘﺎر ﺑﺮﻣﺠﺔ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻘﺎت ‪ API‬اﻟﻤﻨﺎﺳﺒﺔ ﻟﺘﻄﺒﻴﻘﻚ‬
‫ﻋﻨﺪ ﺑﺪء ﻣﺸﺮوع ﺟﺪﻳﺪ ﻟﻸﻧﺪروﻳﺪ ﺗﻈﻬﺮ ﺷﺎﺷﺔ إﺧﺘﻴﺎر اﺻﺪار واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ ﻛﻤﺎ ﻓﻲ اﻟﺼﻮرة‪ ،‬وﻫﺬا اﻹﺧﺘﻴﺎر ﻣﻮﺟﻮد ﻟﺴﺒﺒﻴﻦ‪:‬‬
‫ﺗﻮﺿﻴﺢ ﻋﺪد اﻟﻤﺴﺘﺨﺪﻣﻴﻦ أو اﻷﺟﻬﺰة اﻟﺬﻳﻦ ﻳﺴﺘﻄﻴﻌﻮن ﺗﺜﺒﻴﺖ ﺑﺮﻧﺎﻣﺠﻚ ﺣﺴﺐ اﺻﺪار اﻟـ ‪ API‬اﻟﺬى ﺳﺘﺨﺘﺎره‬ ‫‪1‬‬
‫وﻛﻠﻤﺎ ﻗﻞ رﻗﻢ اﻻﺻﺪار ﻛﻠﻤﺎ اﺳﺘﻬﺪﻓﺖ اﺟﻬﺰة اﻛﺘﺮ وﻣﺴﺘﺨﺪﻣﻴﻦ اﻛﺘﺮ‬
‫ﻗﺪ ﺗﻜﻮن ﻫﻨﺎك ﻣﻤﻴﺰات ﻻ ﺗﺪﻋﻤﻬﺎ ﻧﺴﺨﺔ ‪ API‬أﻗﺪم ﻓﺈذا اﺧﺘﺮت ﻣﺜﻼ آﻳﺲ ﻛﺮﻳﻢ ﺳﺎﻧﺪوﻳﺶ وﺗﻜﻮن ﻫﺬه اﻟﻤﻤﻴﺰات ﻓﻘﻂ‬ ‫‪2‬‬
‫ﻟﻨﺴﺨﺔ ﻛﺖ ﻛﺎت ﻓﻤﺎ ﻓﻮق ﻓﻠﻦ ﻳﻌﻤﻞ اﻟﺘﻄﺒﻴﻖ أو ﺳﺘﻈﻬﺮ أﺧﻄﺎء ﻋﻨﺪ اﻟﺘﺸﻐﻴﻞ‪.‬‬

‫اﺧﺘﻴﺎر ﺑﺮﻣﺠﺔ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ‬ ‫اﺧﺘﻴﺎر ﺑﺮﻣﺠﺔ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ‬

‫ﻗﻮاﻋﺪ إدراج اﻟﺼﻮر اﻟﻤﻨﺎﺳﺒﺔ ﻟﻠﺘﻄﺒﻴﻖ‬

‫ﺗﻮﺿﻊ اﻟﺼﻮر ﻋﺎدة ﻓﻲ اﻟﻤﺠﻠﺪ ‪ drawable‬وﻳﺘﻢ اﻹﺷﺎرة إﻟﻴﻬﺎ ﺑﺎﻟﻜﻮد ‪@drawable/coders.jpg‬‬ ‫‪1‬‬
‫ﻳﺪﻋﻢ اﻷﻧﺪرﻳﻮد ﺣﺎﻟﻴﺎ اﻟﺼﻮر ﻣﻦ ﻧﻮع ‪ bmp, gif, jpg, png‬وﻛﺬﻟﻚ ‪ webp‬ﻟﻨﺴﺨﺔ ‪ Android 4.0‬ﻓﻤﺎ ﻓﻮق‬ ‫‪2‬‬
‫‪1coders.jpg‬‬ ‫ﻳﺠﺐ أن ﻳﻜﻮن اﺳﻢ اﻟﺼﻮرة ﺑﺎﻟﺤﺮوف اﻹﻧﺠﻠﻴﺰﻳﺔ اﻟﺼﻐﻴﺮة ﻣﻦ دون ﻣﺴﺎﻓﺎت وﻻ ﻳﺒﺪأ ﺑﺮﻗﻢ ‪coDers.jpg‬‬ ‫‪3‬‬
‫‪Coders.jpg‬‬ ‫‪coders.jpg‬‬
‫أﺣﺠﺎم اﻟﺼﻮر ﺑﺎﺧﺘﻼف أﺣﺠﺎم ﺷﺎﺷﺎت اﻷﺟﻬﺰة ﻳﻔﻀﻞ أن ﺗﻜﻮن ﻋﻠﻰ ﻋﺪة ﻛﺜﺎﻓﺎت‬ ‫‪4‬‬
‫ﻛﺜﺎﻓﺔ اﻟﺒﻜﺴﻞ‪ dpi‬أﺻﻐﺮ أﺑﻌﺎد‬ ‫أﺑﻌﺎد اﻟﺼﻮرة‬
‫‪426 x 320‬‬ ‫‪120‬‬ ‫ﺻﻐﻴﺮة‬ ‫‪ldpi‬‬
‫‪470 x 320‬‬ ‫‪160‬‬ ‫ﻣﺘﻮﺳﻄﺔ‬ ‫‪mdpi‬‬
‫‪640 x 480‬‬ ‫‪240‬‬ ‫ﻛﺒﻴﺮة‬ ‫‪hdpi‬‬
‫‪960 x 720‬‬ ‫‪320‬‬ ‫ﻛﺒﻴﺮة ﺟﺪا‬ ‫‪xhdpi‬‬
‫‪1280 x 960‬‬ ‫‪480‬‬ ‫ﻛﺒﻴﺮة ﺟﺪا ﺟﺪا‬ ‫‪xxhdpi‬‬
‫‪1920 x 1440‬‬ ‫‪640‬‬ ‫‪ xxxhdpi‬ﻛﺒﻴﺮة ﺟﺪا ﺟﺪا ﺟﺪا‬

‫ﻳﻤﻜﻨﻚ ﻣﻦ ﺧﻼل ﻫﺬا اﻟﻤﻮﻗﻊ اﻟﺬي ﺻﻤﻤﻪ أﺣﺪ اﻷﺧﻮة ﻣﻦ ﻣﺼﺮ ﺗﺤﻮﻳﻞ اﻟﺼﻮر ﺑﺄﺣﺠﺎم ﻣﺨﺘﻠﻔﺔ ﻟﻺﺳﺘﺨﺪام ﻟﻠﺘﻄﺒﻴﻘﺎت‬
‫‪https://appicon.co/#image-sets‬‬

‫‪11‬‬
‫ﺑﻌﺾ اﻹﺧﺘﺼﺎرات اﻟﻤﻔﻴﺪة‬

‫ﻹﻋﺎدة ﺗﻨﺴﻴﻖ اﻟﻨﺺ اﻟﺒﺮﻣﺠﻲ اذﻫﺐ إﻟﻰ ﻗﺎﺋﻤﺔ ‪ Code‬واﺧﺘﺮ ‪Reformat Code‬‬ ‫‪1‬‬
‫ﻟﺘﺮﺗﻴﺐ اﻟﻤﻤﻴﺰات ﻟﻠﻌﻨﺎﺻﺮ ﺣﺴﺐ ﺗﻌﻠﻴﻤﺎت أﻧﺪرﻳﻮد اﻟﺒﺮﻣﺠﻴﺔ اذﻫﺐ إﻟﻰ ﻗﺎﺋﻤﺔ ‪ Code‬واﺧﺘﺮ ‪RearrangeCode‬‬ ‫‪2‬‬

‫اﻟﺪرس اﻟﺴﺎدس‪ :‬ﺟﻌﻞ اﻟﺘﻄﺒﻴﻖ ﺗﻔﺎﻋﻠﻴﺎ ‪١-‬‬ ‫‪6‬‬


‫ﺑﺮﻣﺠﺔ ﻣﻠﻔﺎت ﺟﺎﻓﺎ‬

‫ﺗﺴﺘﺨﺪم ﻣﻠﻔﺎت ﺟﺎﻓﺎ ﻟﻜﺘﺎﺑﺔ اﻟﻜﻮدات اﻟﺒﺮﻣﺠﻴﺔ ورﺑﻂ اﻟﻌﻨﺎﺻﺮ ﻓﻲ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ ﺑﺄواﻣﺮ ﺑﺮﻣﺠﻴﺔ ﻟﻠﺘﺤﻜﻢ ﺑﻬﺎ اﻟﺨﺎﺻﺔ‬
‫ﺑﻬﺎ وﻳﺴﺘﺨﺪم أﻧﺪرﻳﻮد اﺳﺘﻮدﻳﻮ ﻣﻜﺘﺒﺎت ﺟﺎﻓﺎ ﺧﺎﺻﺔ ﺑﺎﻷﻧﺪرﻳﻮد ﺣﻴﺚ أن اﻟﺠﺎﻓﺎ ﺗﺪﻋﻢ أﻳﻀﺎ ﻣﻜﺘﺒﺎت ﻣﻨﺼﺎت أﺧﺮى‪.‬‬
‫ﺣﻴﻦ ﻓﺘﺢ اﻟﺘﻄﺒﻴﻖ ﻷول ﻣﺮة ﺳﻴﻜﻮن ﻫﻨﺎك ﻣﻠﻒ ﺟﺎﻓﺎ ﺑﺎﺳﻢ ‪ MainActivity.java‬ﻳﻀﺎف ﻣﻠﻒ اﻟﺠﺎﻓﺎ ﻫﺬا ﺗﻠﻘﺎﺋﻴﺎ ﻓﻲ اﻟﻤﺴﺎر‬
‫‪java>com.example.android.appname‬‬

‫ﻛﻞ ﻣﻠﻒ ﻣﻦ ﻳﻤﺜﻞ ‪ Class‬وﻳﻤﻜﻦ أن ﻳﻜﻮن اﻟﻜﻼس ﻣﻦ ﻧﻮع ﻧﺸﺎط ‪ Activity‬اﻟﻨﺸﺎط ﻳﻘﺪم ﺷﻴﺌﺎ واﺣﺪا ﻳﻤﻜﻦ ﻟﻠﻤﺴﺘﺨﺪم ﻓﻌﻠﻪ‬
‫وﺑﻌﺾ اﻷﺣﻴﺎن ﻳﻜﻮن ﺷﺎﺷﺔ واﺣﺪة وأﺣﻴﺎﻧﺎ ﻳﻜﻮن ﻫﻨﺎك ﻋﺪة ﺷﺎﺷﺎت ﻟﻠﻨﺸﺎط اﻟﻮاﺣﺪ‪ ،‬وﺑﺎﻷﺳﺎس اﻟﻨﺸــﺎط ﻫﻮ ﻛﻴﻔﻴــﺔ‬
‫ﻋﺮﺿﻚ ﻟﻠﻤﺨﻄﻂ وﻛﻴﻔﻴﺔ ﺗﻔﺎﻋﻠﻪ ﻣﻊ اﻟﻤﺴﺘﺨﺪم‬

‫ﻣﺜﺎل رﺑﻂ ﻋﻨﺼﺮ واﺟﻬﺔ ﺑﺄواﻣﺮ ﺟﺎﻓﺎ‬

‫ﻫﺬا اﻟﻤﺜﺎل ﺳﻴﺮﺑﻂ أﻣﺮ اﻟﻀﻐﻂ ﻋﻠﻰ زر ‪ Button‬ﻓﻲ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ ﺛﻢ ﺳﻴﻐﻴﺮ اﻟﻜﺘﺎﺑﺔ ﻓﻲ ﻋﻨﺼﺮ ﻧﺺ ‪TextView‬‬
‫وﺳﻨﺴﺘﺨﺪم اﻟﻤﻴﺰة ‪ android:onClick‬ﻟﻬﺬا اﻟﻐﺮض واﻟﺘﻲ ﺳﻴﺘﻢ إﺿﺎﻓﺘﻬﺎ ﻟﻠﻌﻨﺼﺮ ‪. Button‬‬

‫‪Button‬‬ ‫"‪android:OnClick="submitOrder‬‬ ‫‪MainActivity.java‬‬

‫‪submitOrder Method‬‬
‫اﻟﻄﺮﻳﻘﺔ ‪ Method‬ﺗﻘﻮم ﺑﻤﺮاﻗﺒﺔ ﺣﺼﻮل اﻟﺤﺪث ‪ OnClick‬وﻫﻮ اﻟﻀﻐﻂ ﻋﻠﻰ اﻟﺰر ‪ Button‬وﺛﻢ أي أواﻣﺮ ﻧﻘﻮم ﺑﺈﺿﺎﻓﺘﻬﺎ‬
‫ﻓﻲ اﻟﻄﺮﻳﻘﺔ ﺳﻴﻘﻮم اﻟﺘﻄﺒﻴﻖ ﺑﺘﻨﻔﻴﺬه‪ ،‬ﻧﻘﻮم ﺑﻌﻤﻞ اﻟﻄﺮﻳﻘﺔ ﺗﻠﻘﺎﺋﻴﺎ ﻛﻤﺎ ﻓﻲ اﻟﺼﻮرة أدﻧﺎه‪،‬‬

‫‪<Button‬‬
‫"‪android:layout_width="wrap_content‬‬
‫"‪android:layout_height="wrap_content‬‬
‫"‪android:text="Order‬‬
‫>‪android:OnClick="submitOrder"/‬‬

‫{ )‪public void submitOrder(View view‬‬


‫;)‪display(2‬‬ ‫ﺳﻴﺘﻢ وﺿﻊ اﻟﻜﻮدات‬
‫}‬
‫ﺑﻴــــــﻦ اﻟﻘﻮﺳﻴــــﻦ‬
‫{ )‪private void display(int number‬‬
‫;)‪TextView quantityTextView = (TextView) findViewById(R.id.quantity_text_view‬‬
‫;)‪quantityTextView.setText("" + number‬‬
‫}‬

‫‪12‬‬
‫ﺷﺮح اﻟﻜﻮدات اﻟﺴﺎﺑﻘﺔ‬
‫ﻫﻨﺎك ﻃﺮﻳﻘﺘﺎن‪ ,‬اﻟﻄﺮﻳﻘﺔ اﻷوﻟﻰ )(‪ submitOrder‬ﺳﺘﺸﻴﺮ إﻟﻰ اﻟﻄﺮﻳﻘﺔ اﻟﺜﺎﻧﻴﺔ ﻋﻦ ﻃﺮﻳﻖ )‪ display(2‬اﻟﻄﺮﻳﻘﺔ‬
‫اﻟﺜﺎﻧﻴﺔ ﺑﺪورﻫﺎ ﺳﺘﻘﻮم ﺑﺎﻟﺘﺤﻜﻢ ﺑﺎﻟﻨﺺ ‪ TextView‬اﻟﺬي ﺗﻢ رﺑﻄﻪ ﻣﻊ ﻋﻨﺼﺮ اﻟﻌﺮض ‪ quantity_text_view‬وﺳﻴﻘﻮم‬
‫ﺑﻌﺮض اﻟﺮﻗﻢ ‪ 2‬ﻋﻠﻴﻪ ﻋﻨﺪ اﻟﻀﻐﻂ ﻋﻠﻰ اﻟﺰر وﻛﻞ ﻫﺬا ﺣﺼﻞ ﻷﻧﻨﺎ ﻓﻲ اﻟﺒﺪاﻳﺔ أﺿﻔﻨﺎ ‪ android:OnClick‬إﻟﻰ اﻟﺰر‬

‫‪COMMENTS‬‬ ‫ﻛﺘﺎﺑﺔ اﻟﻤﻼﺣﻈﺎت داﺧﻞ ﻣﻠﻔﺎت ‪ JAVA‬و ‪XML‬‬


‫اﻟﻬﺪف ﻣﻦ اﻟﻤﻼﺣﻈﺎت ﻫﻮ وﺻﻒ اﻟﻜﻮد ﺑﻄﺮﻳﻘﺔ ﻣﺎ ﻳﻤﻜﻦ وﺻﻔﻪ ﺑﺎﻟﻠﻐﺔ اﻹﻧﺠﻠﻴﺰﻳﺔ أو اﻟﻌﺮﺑﻴﺔ أو أي ﻟﻐﺔ أﺧﺮى ﻟﻴﺲ‬
‫ﻣﻦ اﻟﻀﺮوري أن ﺗﺘﺒﻊ ﺗﻨﺴﻴﻖ ﻟﻐﺔ اﻟﺒﺮﻣﺠﺔ أو ﻗﻮاﻋﺪﻫﺎ ﻓﻤﺜﻼ ﻳﻤﻜﻦ اﺳﺘﺨﺪام اﻟﻤﻼﺣﻈﺎت أﻋﻠﻰ اﻟﻄﺮﻳﻘﺔ ﻟﺸﺮح ﻋﻤﻞ‬
‫اﻟﻜﻮدات ﺑﺪاﺧﻠﻬﺎ‪ .‬وﻫﺬه اﻟﻤﻼﺣﻈﺎت ﺳﺘﺴﺎﻋﺪك وﺗﺴﺎﻋﺪ ﻏﻴﺮك ﻋﻠﻰ ﻓﻬﻢ آﻟﻴﺔ ﻋﻤﻞ اﻟﻜﻮدات ﺑﺴﻬﻮﻟﺔ‬

‫‪/* text */‬‬ ‫ﻳﺠﺐ أن ﺗﺒﺪأ اﻟﻤﻼﺣﻈﺎت وﺗﻨﺘﻬﻲ‬ ‫ﻣﻼﺣﻈﺎت ‪JAVA‬‬ ‫ﻣﻼﺣﻈﺎت ‪XML‬‬
‫ﺑﻬﺬه اﻟﻄﺮﻳﻘﺔ ﺣﺘﻰ وإن ﻛﺎﻧﺖ‬ ‫ﻣﻼﺣﻈﺎت اﻟﺠﺎﻓﺎ ﻳﻤﻜﻦ ﻛﺘﺎﺑﺘﻬﺎ‬ ‫>‪<!-- Blah Blah Blah --‬‬
‫‪/** text */‬‬ ‫اﻟﻤﻼﺣﻈﺔ ﻋﻠﻰ ﻋﺪة أﺳﻄﺮ‬ ‫ﺑﺜﻼث ﻃﺮق ﻣﺨﺘﻠﻔﺔ‪ ،‬ﺑﻌﻀﻬﺎ‬ ‫اﻟﻤﻼﺣﻈﺎت‬
‫ﻟﺴﻄﺮ واﺣﺪ واﻟﺒﻌﺾ اﻵﺧﺮ ﻷﻛﺜﺮ‬
‫‪// text‬‬ ‫ﻫﺬه اﻟﻄﺮﻳﻘﺔ ﻟﺴﻄﺮ واﺣﺪ ﻓﻘﻂ‬ ‫ﻣﻦ ﺳﻄﺮ‬
‫ﻳﺠﺐ أن ﺗﺒﺪأ اﻟﻤﻼﺣﻈﺎت وﺗﻨﺘﻬﻲ‬
‫**‪/‬‬
‫‪<!--‬‬ ‫ﺑﻬﺬه اﻟﻄﺮﻳﻘﺔ ﺣﺘﻰ وإن ﻛﺎﻧﺖ‬
‫‪* The HelloWorldApp class implements an application that‬‬
‫‪* simply displays "Hello World!" to the standard output.‬‬
‫ﻣﺜﺎل‬ ‫‪Blah‬‬
‫‪*/‬‬ ‫>‪Blah Blah --‬‬ ‫اﻟﻤﻼﺣﻈﺔ ﻋﻠﻰ ﻋﺪة أﺳﻄﺮ‬

‫ﻋﻨﺪ إﺿﺎﻓﺔ ﻃﺮﻳﻘﺔ ‪ Method‬إﻟﻰ اﻟﻨﺸﺎط ‪ Activity‬ﻳﺠﺐ إﺿﺎﻓﺘﻬﺎ ﺑﻴﻦ ﺑﻌﺾ اﻟﺪوال ﺗﺤﺘﺎج إﻟﻰ اﺳﺘﻴﺮاد ﻣﻜﺘﺒﺔ ﻛﻮدات‬
‫ﻗﻮﺳﻲ اﻟﻨﺸﺎط وﺧﺎرج إﻃﺎر اﻟﻄﺮق اﻷﺧﺮى ﻛﻤﺎ ﻫﻮ ﻣﻮﺿﺢ ﺧﺎﺻﺔ واﻹﺷﺎرة إﻟﻴﻬﺎداﺧﻞ اﻟﻨﺸﺎط ﻟﻜﻲ ﺗﻌﻤﻞ‬
‫{ ‪Activity‬‬
‫;‪import java.text.NumberFormat‬‬
‫{ )(‪onCreate‬‬
‫{ ‪Activity‬‬ ‫{ )(‬
‫‪th‬‬ ‫‪od3‬‬
‫}‬ ‫‪me‬‬
‫{)(‪method‬‬
‫)(‪NumberFormat.getCurrencyInstance‬‬ ‫{ )(‪method2‬‬ ‫}‬
‫}‬
‫}‬
‫}‬
‫ﻟﻜﻲ ﺗﻌﻤﻞ ﻫﺬه اﻟﺪاﻟﺔ ﻳﺠﺐ اﻹﺷﺎرة إﻟﻲ‬
‫ﻫﺬه اﻟﻤﻜﺘﺒﺔ ﻓﻲ اﻷﻋﻠﻰ ﺧﺎرج اﻟﻨﺸﺎط‬ ‫}‬

‫ﺗﻔﻌﻴﻞ اﻟـ ‪ import‬اﻟﺘﻠﻘﺎﺋﻲ ﻟﻤﻜﺘﺒﺎت اﻟﻜﻮدات‬


‫ﻋﻨﺪ ﺗﻔﻌﻴﻞ ﻫﺬه اﻟﺨﺎﺻﻴﺔ ﻣﻦ اﻟﺨﻴﺎرات ﺳﻴﻘﻮم أﻧﺪرﻳﻮد اﺳﺘﻮدﻳﻮ ﺑﺈﺿﺎﻓﺔ اﻹﺳﺘﻴﺮاد ﺗﻠﻘﺎﺋﻴﺎ ﻋﻨﺪ اﻟﺤﺎﺟﺔ إﻟﻴﻬﺎ وذﻟﻚ‬
‫ﻷﻏﻠﺐ ﻣﻜﺘﺒﺎت اﻟﻜﻮدات‬
‫‪preferences (settings) >Editor>General>Auto Import‬‬ ‫‪Add unambiguous imports on the fly‬‬

‫‪13‬‬
‫اﻟﻤﺘﻐﻴﺮات ‪VARIABLES‬‬
‫‪ Literal‬ﻫﻲ ﻗﻴﻢ ﺛﺎﺑﺘﺔ ﻻ ﺗﺘﻐﻴﺮ ﻣﺜﻞ ‪2،22،55‬‬ ‫ﺗﻌﺮﻳﻒ اﻟﻤﺘﻐﻴﺮات ‪Variables Declaration‬‬ ‫‪1‬‬
‫‪ variables‬ﻫﻲ ﻗﻴﻢ ﻣﺘﻐﻴﺮة ﻳﺴﺘﺨﺪم ﻟﻬﺎ اﺳﻢ وﻳﻤﻜﻦ‬
‫ﺗﻐﻴﻴﺮ ﻗﻴﻤﺘﻬﺎ ﻣﺜﻞ ‪numberOfCoffees = 3‬‬ ‫;‪int numberOfCoffees = 2‬‬
‫‪numberOfCoffees = 5x5‬‬
‫‪Data‬‬ ‫‪Variable‬‬ ‫‪Initial‬‬
‫ﻳﺤﺪد ﻧﻮع اﻟﺒﻴﺎﻧﺎت ﻫﻨﺎ‬
‫ﻧﻮع ﻗﻴﻢ ﺑﻴﺎﻧﺎت اﻟﻤﺘﻐﻴﺮ‬
‫‪type‬‬
‫ﻧﻮع اﻟﺒﻴﺎﻧﺎت‬
‫‪name‬‬
‫اﺳﻢ اﻟﻤﺘﻐﻴﺮ‬
‫=‬ ‫‪value‬‬
‫اﻟﻘﻴﻤﺔ‬
‫;‬
‫اﻟﻤﺒﺪﺋﻴﺔ‬
‫أﻧﻮاع اﻟﺒﻴﺎﻧﺎت اﻟﺒﺪاﺋﻴﺔ اﻟﻤﺪﻋﻮﻣﺔ ﻣﻦ ﺟﺎﻓﺎ‬
‫‪Primitive Data Types supported by java‬‬ ‫‪2‬‬
‫ﻣﺪى اﻟﻘﻴﻢ اﻟﻤﻤﻜﻦ ﺗﺨﺰﻳﻨﻬﺎ‬ ‫اﻓﺘﺮاﺿﻴﺔ‬ ‫اﻟﺴﻌﺔ‬ ‫اﻟﻮﺻﻒ‬ ‫ﻧﻮع اﻟﺒﻴﺎﻧﺎت‬
‫‪-128‬‬ ‫‪127‬‬ ‫‪0‬‬ ‫‪ 1‬ﺑﺎﻳﺖ‬ ‫ﺑﺎﻳـــﺖ‬ ‫‪byte‬‬
‫‪-32,768‬‬ ‫‪32,767‬‬ ‫‪0‬‬ ‫ﻋﺪد ﺻﺤﻴﺢ ﻗﺼﻴﺮ ‪ 2‬ﺑﺎﻳﺖ‬ ‫‪short‬‬
‫‪-231‬‬ ‫‪231-1‬‬ ‫‪0‬‬ ‫‪ 4‬ﺑﺎﻳﺖ‬ ‫ﻋﺪد ﺻﺤﻴﺢ‬ ‫‪int‬‬
‫‪-263‬‬ ‫‪263-1‬‬ ‫‪0L‬‬ ‫ﻋﺪد ﺻﺤﻴﺢ ﻃﻮﻳﻞ ‪ 8‬ﺑﺎﻳﺖ‬ ‫‪long‬‬
‫‪3.4e−38‬‬ ‫‪3.4e38‬‬ ‫‪0.0f‬‬ ‫‪ 4‬ﺑﺎﻳﺖ‬ ‫ﻋﺪد ﻧﺴﺒﻲ‬ ‫‪float‬‬
‫‪1.7e-38‬‬ ‫‪1.7e+38‬‬ ‫‪0.0d‬‬ ‫ﻋﺪد ﻧﺴﺒﻲ ﻣﻀﺎﻋﻒ ‪ 8‬ﺑﺎﻳﺖ‬ ‫‪double‬‬
‫‪false‬‬ ‫‪true‬‬ ‫‪false‬‬ ‫‪ 1‬ﺑـﺖ‬ ‫ﻗﻴﻤﺔ ﻣﻨﻄﻘﻴﺔ‬ ‫‪boolean‬‬
‫)‪u0000 (0‬‬ ‫)‪uffff (65,535‬‬ ‫'‪'\u0000‬‬
‫‪or 0‬‬ ‫‪ 2‬ﺑﺎﻳﺖ‬ ‫ﺣــﺮف‬ ‫‪char‬‬
‫ﻣﻼﺣﻈﺔ‪ :‬ﻻ ﻳﻮﺟﺪ ﻧﻮع ﺑﻴﺎﻧﺎت ﻋﺪدي ﻳﻌﻄﻲ ﻟﻠﻘﻴﻢ اﻟﻤﻮﺟﺒﺔ ﻓﻘﻂ ﻟﻜﻦ ﻳﻤﻜﻦ ﺗﺤﺪﻳﺪ اﻟﻘﻴﻢ ﻋﻦ ﻃﺮﻳﻖ اﻟﻜﻮدات اﻟﺒﺮﻣﺠﻴﺔ‬

‫ﺷﺮوط وأﻓﻀﻠﻴﺎت ‪ . . .‬ﻋﻨﺪ ﺗﺴﻤﻴﺔ اﻟﻤﺘﻐﻴﺮات‬

‫ﻻ ﻳﻤﻜﻦ اﺳﺘﺨﺪام اﻟﻜﻠﻤﺎت اﻟﻤﻔﺘﺎﺣﻴﺔ واﻟﻤﺤﺠﻮزة‬ ‫‪5‬‬ ‫اﺳﻢ اﻟﻤﺘﻐﻴﺮ ﺣﺴﺎس ﻟﺤﺎﻟﺔ اﻟﺤﺮف )ﺻﻐﻴﺮ‬ ‫‪1‬‬
‫;‪int int = 2‬‬ ‫ﻷواﻣﺮ ﺟﺎﻓﺎ‪ ،‬ﻛﺈﺳﻢ ﻟﻤﺘﻐﻴﺮ‬ ‫أم ﻛﺒﻴﺮ( وﻋﻨﺪ اﻹﺷﺎرة إﻟﻴﻪ ﻓﻲ اﻟﻜﻮدات‬
‫)ﻗﺎﺋﻤﺔ اﻟﻜﻠﻤﺎت اﻟﻤﻔﺘﺎﺣﻴﺔ ﻓﻲ اﻟﺼﻔﺤﺔ اﻟﺘﺎﻟﻴﺔ(‬
‫;‪int void= 2‬‬ ‫ﻳﺠﺐ أن ﻳﻜﺘﺐ ﻛﻤﺎ ﺗﻢ ﺗﻌﺮﻳﻔﻪ ﺑﺎﻟﻀﺒﻂ‬

‫إذا ﻛﺎﻧﺖ اﺳﻢ اﻟﻤﺘﻐﻴﺮ ﻳﺘﻜﻮن ﻣﻦ ﻛﻠﻤﺔ واﺣﺪة ﻓﻘﻂ‬ ‫‪6‬‬


‫‪orderedCoffee‬‬ ‫=‬ ‫‪OrderedCoffee‬‬
‫ﻓﻴﻜﺘﺐ ﺑﺎﻷﺣﺮف اﻟﺼﻐﻴﺮة ‪ order‬وإذا ﻛﺎن أﻛﺜﺮ ﻣﻦ‬
‫ﻳﻔﻀﻞ داﺋﻤﺎ اﻟﺒﺪء ﺑﺤﺮف ﺻﻐﻴﺮ وﻟﻴﺲ رﻣﺰ‬ ‫‪2‬‬
‫ﻣﺜﻞ ‪ $‬أو ـــ وﻫﺬا ﻻ ﻳﻌﻨﻲ أﻧﻪ ﻻ ﻳﻤﻜﻦ‬
‫ﻛﻠﻤﺔ ﻳﺘﻢ ﺗﻜﺒﻴﺮ أول ﺣﺮف ﻣﻦ ﻛﻠﺔ ﻣﻠﺘﺼﻘﺔ ﺑﻌﺪ ذﻟﻚ‬
‫‪numberOfCoffeOrdered‬‬ ‫اﺳﺘﺨﺪاﻣﻬﺎ وﻟﻜﻦ ﻫﻲ أﻓﻀﻠﻴﺎت اﻟﺒﺮﻣﺠـــﺔ‬

‫إذا ﻛﺎﻧﺖ ﻗﻴﻤﺔ اﻟﻤﺘﻐﻴﺮ ﻫﻲ ﻗﻴﻤﺔ ﺛﺎﺑﺘﺔ دوﻣﺎ ﻓﺈن‬ ‫‪7‬‬ ‫ﻻ ﻳﻤﻜﻦ اﺳﺘﺨﺪام ﻣﺴﺎﻓﺔ ﻓﻲ اﺳﻢ اﻟﻤﺘﻐﻴﺮ‬ ‫‪3‬‬
‫اﺳﻢ اﻟﻤﺘﻐﻴﺮ ﻳﺠﺐ أن ﻳﻜﻮن ﺑﺎﻷﺣﺮف اﻟﻜﺒﻴﺮة ﺑﺎﻟﻜﺎﻣﻞ‬ ‫;‪int ordered Coffee = 2‬‬
‫ووﺿﻊ ﺧﻂ ﺳﻔﻠﻲ ـــ ﺑﻴﻦ ﻛﻞ ﻛﻠﻤﺔ‬
‫;‪NUM_COFFEE = 6‬‬ ‫ﻳﻔﻀﻞ ﻋﺪم اﺳﺘﺨﺪام اﻟﺤﺮوف اﻟﻤﺘﻜﺮرة أو‬ ‫‪4‬‬
‫ﻳﻔﻀﻞ وﺿﻊ ﺣﺮف ‪ m‬ﺻﻐﻴﺮ ﺑﺪاﻳﺔ أﺳﻤﺎء اﻟﻤﺘﻐﻴﺮات‬ ‫‪8‬‬ ‫اﻟﺤﺮوف اﻟﻤﺨﺘﺼﺮة‪ ،‬ﺑﻞ ﻳﻜﺘﺐ اﺳﻢ اﻟﻤﺘﻐﻴﺮ‬
‫اﻟﻤﺤﻠﻴﺔ اﻟﺘﻲ ﻳﺘﻢ اﺳﺘﺨﺪاﻣﻬﺎ داﺧﻞ اﻟﺼﻨﻒ وﺗﻌﻨﻲ‬ ‫ﺑﻜﻠﻤﺔ ﻛﺎﻣﻠﺔ واﺿﺤﺔ اﻟﻤﻌﻨﻰ ﻟﺘﺴﻬﻞ ﻓﻬﻢ‬
‫‪mTextColor‬‬ ‫ﻣﺘﻐﻴﺮ ﻋﻀﻮ )‪(member variable‬‬ ‫‪orderrrrrr ordcfe‬‬ ‫اﻟﻜﻮدات‬

‫‪14‬‬
‫ﻗﺎﺋﻤﺔ ﻣﻌﻈﻢ اﻟﻜﻠﻤﺎت اﻟﻤﻔﺘﺎﺣﻴﺔ ﻟـﺠﺎﻓﺎ ‪KEYWORDS‬‬
‫ﻫﻲ ﻛﻠﻤﺎت وﻋﺒﺎرات ﻣﺤﺠﻮزة ﻷواﻣﺮ ﺟﺎﻓﺎ ﻳﻤﻜﻦ اﺳﺘﺨﺪاﻣﻬﺎ ﻟﺒﺮﻣﺠﺔ اﻷواﻣﺮ ﻟﻠﻘﻴﺎم ﺑﺄﻣﺮ ﻣﺎ ﻣﺜﻞ ﺗﻌﺮف ﻣﺘﻐﻴﺮ أو‬
‫ﺗﺤﺪﻳﺪ ﻧﻮﻋﻪ أو وﻏﻴﻬﺮﻫﺎ ﻣﻦ اﻷواﻣﺮ‪ ،‬ﺑﻤﺎ أﻧﻬﺎ ﻣﺤﺠﻮزة ﻓﻼ ﻳﻤﻜﻦ اﺳﺘﺨﺪاﻣﻪ ﻷﻏﺮاض أﺧﺮى ﻣﺜﻞ ﺗﺴﻤﻴﺔ ﻣﺘﻐﻴﺮ‬
‫ﺑﺄﺣﺪﻫﺎ‪ ،‬ﻓﻌﻨﺪ ذﻟﻚ ﺳﻴﻌﺘﺒﺮ ﻛﺨﻄﺄ ﺑﺮﻣﺠﻲ ﻣﻦ ﻗﺒﻞ ﻣﺼﺤﺤﺎت أﺧﻄﺎء ﺟﺎﻓﺎ اﻟﺒﺮﻣﺠﻴﺔ‬
‫‪abstract‬‬ ‫‪continue‬‬ ‫‪for‬‬ ‫‪new‬‬ ‫‪switch‬‬
‫***‪assert‬‬ ‫‪default‬‬ ‫*‪goto‬‬ ‫‪package‬‬ ‫‪synchronized‬‬
‫‪boolean‬‬ ‫‪do‬‬ ‫‪if‬‬ ‫‪private‬‬ ‫‪this‬‬
‫‪break‬‬ ‫‪double‬‬ ‫‪implements‬‬ ‫‪protected‬‬ ‫‪throw‬‬
‫‪byte‬‬ ‫‪else‬‬ ‫‪import‬‬ ‫‪public‬‬ ‫‪throws‬‬
‫‪case‬‬ ‫****‪enum‬‬ ‫‪instanceof‬‬ ‫‪return‬‬ ‫‪transient‬‬
‫‪catch‬‬ ‫‪extends‬‬ ‫‪int‬‬ ‫‪short‬‬ ‫‪try‬‬
‫‪char‬‬ ‫‪final‬‬ ‫‪interface‬‬ ‫‪static‬‬ ‫‪void‬‬
‫‪class‬‬ ‫‪finally‬‬ ‫‪long‬‬ ‫**‪strictfp‬‬ ‫‪volatile‬‬
‫*‪const‬‬ ‫‪float‬‬ ‫‪native‬‬ ‫‪super‬‬ ‫‪while‬‬

‫ﺗﺼﺤﻴﺢ اﻷﺧﻄﺎء ‪DEBUGGING‬‬


‫ﻣﻦ ﺷﺄن ﻣﺘﻌﻘﺐ اﻷﺧﻄﺎء ﻣﺴﺎﻋﺪﺗﻨﺎ ﻓﻲ اﻛﺘﺸﺎف واﺻﻼح اﻷﺧﻄﺎء ﻓﻲ اﻟﻜﻮد‪ ،‬واﻟﺠﻴﺪ ﻓﻲ ﻣﺼﺤﺢ اﻷﺧﻄﺎء أﻧﻪ ﻳﻤﻜﻨﻚ‬
‫ﺗﻮﻗﻴﻒ اﻟﺘﻄﺒﻴﻖ ﻋﻨﺪ ﻧﻘﻄﺔ ﻣﻌﻴﻨﺔ وﺑﻌﺪ ذﻟﻚ ﻳﻤﻜﻨﻨﺎ ﻓﺤﺺ ﺣﺎﻟﺔ اﻟﺘﻄﺒﻴﻖ ﺑﺎﻟﻜﺎﻣﻞ‪.‬‬
‫‪ 1‬ﻳﻤﻜﻦ وﺿﻊ ﻧﻘﻄﺔ إﻳﻘﺎف ‪ Break Point‬ﻋﻨﺪ ﺳﻄﺮ ﻣﻌﻴﻦ ﺑﺎﻟﻀﻐﻂ ‪ 3‬ﻋﻨﺪﻣﺎ ﻳﺼﻞ اﻟﺘﻄﺒﻴﻖ إﻟﻰ اﻟﻨﻘﻄﺔ اﻟﺘﻲ‬
‫ﺣﺪدﻧﺎﻫﺎ ﻓﻲ اﻷﻛﻮاد ﺳﻴﺘﻮﻗﻒ اﻟﺘﻄﺒﻴﻖ‬ ‫ﻋﻠﻰ ﻳﺴﺎر اﻟﺴﻄﺮ ﻹﻳﻘﺎف اﻟﺘﻄﺒﻴﻖ ﻋﻨﺪه ﻋﻨﺪ اﻟﺘﺸﻐﻴﻞ‬
‫ﻣﺆﻗﺘﺎ وﻳﺤﺪد اﻟﺴﻄﺮ اﻟﺬي اﺧﺘﺮﻧﺎه ﻓﻲ‬
‫اﻟﺨﻄﻮة اﻷوﻟﻰ وإذا ﻛﺎن ﻣﺜﻼ ﺗﻌﺮﻳﻒ‬
‫ﻟﻤﺘﻐﻴﺮ‪ ،‬ﻓﺴﺘﻈﻬﺮ ﻗﻴﻤﺘﻪ ﻋﻨﺪ اﻟﻀﻐﻂ‬
‫ﻋﻠﻰ زر ‪ Step Over‬واﻟﺬي ﺑﺪوره ﺳﻴﺤﺮك‬
‫ﺗﺸﻐﻴﻞ اﻟﺘﻄﺒﻴﻖ ﺳﻄﺮا واﺣﺪ ﻟﻸﺳﻔﻞ وﻣﻦ‬
‫ﺛﻢ ﺳﺘﻈﻬﺮ ﻗﻴﻤﺔ اﻟﻤﺘﻐﻴﺮ ﻓﻲ اﻟﺸﺎﺷﺔ‬
‫ﻓﻲ اﻷﺳﻔﻞ ﻛﻤﺎ ﻓﻲ اﻟﺼﻮرة‬

‫ﻟﺘﺸﻐﻴﻞ وﺿﻊ ﺗﺼﺤﻴﺢ اﻷﺧﻄﺎء ﻳﺠﺐ اﺧﺘﻴﺎر ‪Run>Debug‬‬ ‫‪2‬‬

‫‪Step Over‬‬

‫‪15‬‬
‫اﻟﺨﻮارزﻣﻴﺔ ‪PSEUDO CODE‬‬
‫اﻟﺨﻮارزﻣﻴﺔ ﻫﻲ وﺻﻒ ﻣﺘﻘﺪم ﻟﺸﺮح ﺧﻄﻮات ﻋﻤﻞ اﻟﺘﻄﺒﻴﻖ وﻫﺬا ﻳﺴﺎﻋﺪﻧﺎ ﻋﻠﻰ وﺿﻊ أﻓﻜﺎرﻧﺎ ﺑﺸﻜﻞ ﺧﻄﻲ‬
‫ﻣﺘﺴﻠﺴﻞ ﻟﻤﺎ ﻧﺮﻳﺪ ﺣﺪوﺛﻪ ﺧﻄﻮة ﺗﻠﻮ اﻷﺧﺮى وﻻ ﺗﻮﺟﺪ ﺿﻮاﺑﻂ ﻟﺒﻨﺎء اﻟﺨﻮارزﻣﻴﺔ ﻓﻘﻂ ﻋﻠﻴﻨﺎ ﺗﻀﻤﻴﻦ اﻟﺘﻔﺎﺻﻴﻞ اﻟﺘﻲ‬
‫ﺳﺘﻔﻴﺪﻧﺎ ﻓﻲ ﻛﺘﺎﺑﺔ اﻟﻨﺺ اﻟﺒﺮﻣﺠﻲ‪.‬‬
‫ﻣﺜﺎل‪ :‬ﺗﺤﺪﻳﺚ ﻗﻴﻤﺔ ﻣﺘﻐﻴﺮ إﻟﻰ ﻗﻴﻤﺔ اﻟﻤﻌﺎدﻟﺔ‪4 + 2*12 - 8:‬‬
‫اﻟﺨــﻮارزﻣﻴﺔ‬ ‫اﻵﻛﻮاد اﻟﺒﺮﻣﺠﻴﺔ‬
‫‪Create quantity variable, set it to 2‬‬ ‫;‪int quantity = 2‬‬ ‫ﻃﺒــﻖ ﻫﺬا اﻟﻜـﻮد ﻓﻲ‬
‫اﻟﺒﺮﻧﺎﻣﺞ وﺣﺎول ﻣﻌﺮﻓﺔ‬
‫‪Multiply 12 by quantity variable‬‬ ‫;‪quantity = quantity * 12‬‬
‫ﻧﺎﺗﺞ اﻟﻤﻌﺎدﻟﺔ‬
‫‪Add 4 to quantity variable‬‬ ‫;‪quantity = quantity + 4‬‬ ‫? = ‪quantity‬‬
‫‪Subtract 8 to quantity variable‬‬ ‫;‪quantity = quantity - 8‬‬

‫ﻣﺠﺎل اﻟﻤﺘﻐﻴﺮ ‪VARIABLE SCOPE‬‬


‫‪Global‬‬
‫{ ‪Activity‬‬ ‫وﻫﻮ اﻟﻤﺪى اﻟﺬي ﻳﻤﻜﻦ اﺳﺘﺨﺪام اﻟﻤﺘﻐﻴﺮات ﻓﻴﻪ‪ ،‬وﻟﻪ ﻋﺪة أﻧﻮاع‪ ،‬ﻣﻨﻬﺎ‪:‬‬
‫;‪int score = 3‬‬
‫‪Locale‬‬

‫{ )(‪onCreate‬‬
‫;‪int quantity = 2‬‬ ‫اﻟﻤﺪى اﻟﻌﺎﻟﻤﻲ ‪ Global‬وﻳﺘﻢ ﻓﻴﻪ ﺗﻌﺮﻳﻒ اﻟﻤﺘﻐﻴﺮ ﺧﺎرج ﺟﻤﻴﻊ اﻟﻄﺮق ‪ Method‬وﻟﻜﻦ داﺧﻞ‬ ‫‪1‬‬
‫;)‪display(score‬‬ ‫ﻣﺪى اﻟﻜﻼس وﻳﺸﺎر إﻟﻴﻪ ﻓﻲ أي ﻃﺮﻳﻘﺔ ﻣﻮﺟﻮدة ﻓﻲ اﻟﻜﻼس اﻟﺤﺎﻟﻲ‬
‫}‬
‫{ )(‪method‬‬
‫;)‪display(score‬‬
‫;) ‪display(quantity‬‬
‫اﻟﻤﺪى اﻟﻤﺤﻠﻲ ‪ Locale‬وﻳﺘﻢ ﻓﻴﻪ ﺗﻌﺮﻳﻒ اﻟﻤﺘﻐﻴﺮ داﺧﻞ اﻟﻄﺮﻳﻘﺔ ﻓﻘﻂ‪ Method‬وﻟﻦ ﻧﺴﺘﻄﻴﻊ‬ ‫‪2‬‬
‫}‬ ‫اﻹﺷﺎرة إﻟﻴﻪ ﻓﻲ ﻃﺮق أو أﻧﺸﻄﺔ أﺧﺮى ‪Other Methods or Classes‬‬
‫}‬

‫اﻟﺪرس اﻟﺴﺎﺑﻊ‪ :‬ﺟﻌﻞ اﻟﺘﻄﺒﻴﻖ ﺗﻔﺎﻋﻠﻴﺎ ‪٢-‬‬ ‫‪7‬‬


‫اﻟﻤﺨﻄﻄﺎت اﻟﻤﺘﺪاﺧﻠﺔ ‪NESTED VIEWGROUPS‬‬
‫وﻫﻮ ﺗﻀﻤﻴﻦ ﻣﺨﻄﻄﺎت ﻋﺮض ﻓﺮﻋﻴﺔ داﺧﻞ ﻣﺨﻄﻄﺎت ﻋﺮض رﺋﻴﺴﻴﺔ وذﻟﻚ ﻳﻌﻄﻲ‬
‫إﻣﻜﺎﻧﻴﺎت أﻛﺒﺮ ﻓﻲ اﻟﺘﺤﻜﻢ ﻓﻲ ﻣﻮﺿﻊ اﻟﻌﻨﺎﺻﺮ وﻟﻜﻦ ﻳﺮاﻋﻰ أن إذا زاد ﺗﺪاﺧﻞ اﻟﻤﺨﻄﻄﺎت‬
‫ﻛﻠﻤﺎ أﺛﺮ ذﻟﻚ ﻋﻠﻰ أداء اﻟﺘﻄﺒﻴﻖ‪.‬‬
‫‪LinearLayout‬‬

‫‪TextView‬‬ ‫‪LinearLayout‬‬

‫‪TextView‬‬ ‫‪Button‬‬ ‫‪Button‬‬

‫‪16‬‬
‫ﻗﻮاﻋﺪ اﻟﻨﺼﻮص اﻟﻤﺘﺴﻠﺴﺔ ‪STRINGS CONCATENATION ROLES‬‬
‫ﺗﻌﺘﺒﺮ اﻟﻨﺼﻮص اﻟﻤﺘﺴﻠﺴﻠﺔ ﻣﻦ أﻧﻮاع اﻟﺒﻴﺎﻧﺎت اﻟﻜﺎﺋﻦ )‪ (Object‬وﻫﻲ ﺗﺨﺘﻠﻒ ﻓﻲ ﻗﻮاﻋﺪﻫﺎ ﻋﻦ أﻧﻮاع اﻟﺒﻴﺎﻧﺎت اﻟﺒﺪاﺋﻴﺔ‬
‫)‪ ،(Primitive‬وﻋﻨﺪ ﻛﺘﺎﺑﺔ اﻟﻨﺼﻮص ﻓﻲ ﻣﻠﻔﺎت اﻟﺠﺎﻓﺎ ﻳﺠﺐ إﺗﺒﺎع ﻫﺬه اﻟﻘﻮاﻋﺪ ﻟﺘﺠﻨﺐ ﺣﺼﻮل اﻷﺧﻄﺎء ﻓﻲ اﻟﺘﻄﺒﻴﻖ‬
‫اﻟﺤﺮف اﻷول ﻛﺒﻴﺮ ﻷن‬ ‫ﺗﻌﺮﻳﻒ اﻟﻤﺘﻐﻴﺮ ﻣﻦ‬
‫ﺗﺠﺎﻫﻞ اﻟﺤﺮوف اﻟﺨﺎﺻــﺔ‬ ‫ﻧﻮع ﺑﻴﺎﻧﺎت ﻛﺎﺋﻦ ‪Object‬‬ ‫‪1‬‬
‫‪3‬‬ ‫ﻧﻮع ﻧﺼﻮص ‪String‬‬
‫‪ِEscape Special Characters‬‬
‫;””\‪String textToDisplay = “Welcom to \n\”1 Million Coders‬‬
‫ﻟﻮ أردﻧﺎ ﻛﺘﺎﺑﺔ اﻟﺤﺮف )”( ﺿﻤﻦ ﻗﻴﻤﺔ‬
‫ﻗﻴﻤﺔ اﻟﻤﺘﻐﻴﺮ اﻟﻔﻌﻠﻴﺔ‬
‫اﻟﻤﺘﻐﻴﺮ اﻟﻨﺺ ﻓﺴﻴﺤﺪث ﺧﻄﺄ ﻷن ﺳﻴﻌﺘﺒﺮ‬ ‫ﻳﺠﺐ أن ﻳﺒﺪأ وﻳﻨﺘﻬﻲ‬
‫ﻗﻮس اﻏﻼق ﻟﻠﻨﺺ‪ ،‬واﻟﻨﺺ اﻟﺒﺎﻗﻲ ﻳﻌﺘﺒﺮ‬
‫‪Welcom to‬‬
‫اﻟﻨﺺ ﺑﻌﻼﻣﺔ اﻗﺘﺒﺎس‬
‫‪2‬‬
‫”‪”1 Million Coders‬‬
‫ﺧﻄﺄ ;””‪“Welcom to ”1 Million Coder\n‬‬ ‫ﻳﺴﺘﺨﺪم اﻟﺮﻣﺰ ‪ \n‬ﻹدﺧﺎل ﺳﻄﺮ ﺟﺪﻳﺪ ﻓﻲ‬
‫‪error‬‬ ‫‪4‬‬
‫ﻓﻠﻔﺘﺎدي ﻫﺬه اﻟﻤﺸﻜﻠﺔ ﻳﺠﺐ وﺿﻊ ﻋﻼﻣﺔ‬ ‫ﻗﻴﻤﺔ اﻟﻤﺘﻐﻴﺮ ﻓﻤﺎ ﻳﻜﺘﺐ ﺑﻌﺪه ﺳﻴﻜﻮن ﻓﻲ‬
‫)‪ (/‬ﻗﺒﻞ اﻟﻘﻮس ﻓﺴﻴﻔﻬﻢ اﻟﺒﺮﻧﺎﻣﺞ أن ﻫﺬا‬ ‫اﻟﺴﻄﺮ اﻟﺠﺪﻳﺪ‪ ،‬ﻛﻤﺎ ﻓﻲ اﻟﻤﺜﺎل أﻋﻼه‬
‫اﻟﻘﻮس ﻳﺠﺐ ﺗﺠﺎﻫﻠﻪ‬
‫اﻟﻨﺼﻮص ﻣﻤﻜﻦ أن ﺗﺤﺘﻮي ﻋﻠﻰ ﺣﺮوف‪،‬‬
‫‪5‬‬
‫أرﻗﺎم أو رﻣﻮز ﻣﺜﻞ ‪# $‬‬
‫;”‪String textToDisplay = “Welcom” + “ ” + “Hello‬‬ ‫‪ 6‬ﻟﺪﻣﺞ ﻧﺼﻮص ﻣﻊ أرﻗﺎم أو ﻧﺼﻮص ﻳﺴﺘﺨﺪم اﻟﺮﻣﺰ ‪+‬‬
‫;‪String textToDisplay = “Welcom” + 1‬‬ ‫ﻫﻨﺎك ﻋﺪة ﻃﺮق ﻛﺬﻟﻚ ﻟﺪﻣﺞ اﻟﻨﺼﻮص أو اﻷرﻗﺎم‬ ‫‪7‬‬
‫;‪String textToDisplay = 2 + 1‬‬ ‫‪litteral‬‬ ‫ﻣﻨﻬﺎ ;‪x = x + n; = x += n‬‬
‫;‪String textToDisplay = “” + 123‬‬ ‫ﺗﺴﺘﺨﺪم ﻧﻔﺲ اﻟﻄﺮﻳﻘﺔ ﻟﻠﻤﺘﻐﻴﺮات ﻣﻦ ﻧﻮع ‪int‬‬ ‫‪8‬‬
‫;)‪String textToDisplay = String.valueOf(123‬‬ ‫وﻳﻤﻜﻦ اﺳﺘﺨﺪام ;‪r = r + 1; = r++‬‬
‫;)‪String textToDisplay = Integer.toString(123‬‬ ‫ﺗﻘﻮم ﺑﺰﻳﺎدة رﻗﻢ ﻟﻠﻌﺪد وﻟﻠﻄﺮح ﻧﻔﺲ اﻟﻄﺮﻳﻘﺔ أﻳﻀﺎ‬

‫ﺗﻌﺮﻳﻒ اﻟﻄﺮق )‪METHOD DEFINITIONS (SIGNATURE‬‬


‫اﻟﻄﺮﻳﻘﺔ ‪ Method‬ﺗﺴﺘﺨﺪم ﻟﻮﺿﻊ اﻷواﻣﺮ اﻟﺒﺮﻣﺠﻴﺔ داﺧﻠﻬﺎ { )‪Public int textToDisplay(int number, String text‬‬
‫‪...‬‬ ‫واﺳﺘﺨﺪاﻣﻬﺎ ﻓﻲ اﻟﻮﻗﺖ اﻟﻤﻨﺎﺳﺐ‪،‬وﻗﺪ ﻳﺤﺘﻮي اﻟﻨﺸﺎط‬
‫‪...‬‬ ‫ﻋﻠﻰ أﻛﺜﺮ ﻣﻦ ﻃﺮﻳﻘﺔ ﻟﻜﻞ ﻣﻨﻬﺎ أواﻣﺮﻫﺎ اﻟﺒﺮﻣﺠﻴﺔ اﻟﺨﺎﺻﺔ ‪.‬‬
‫}‬
‫ﻳﻤﻜﻦ اﻟﻮﺻﻮل إﻟﻰ اﻷواﻣﺮ داﺧﻞ اﻟﻄﺮﻳﻘﺔ ﻋﻦ ﻃﺮﻳﻖ اﺳﺘﺪﻋﺎء‬
‫اﺳﻤﻬﺎ ﻣﻦ ﻃﺮﻳﻘﺔ أﺧﺮى أو ﻣﻦ ﻧﺸﺎط آﺧﺮ‪ ،‬وإذا ﻛﺎن‬
‫اﻟﺘﻌﺮﻳﻒ اﻷوﻟﻲ ﻟﻠﻄﺮﻳﻘﺔ ﻳﺤﺘﻮى ﻋﻠﻰ ﻋﻮاﻣﻞ ‪ Parameters‬ﻓﻴﺠﺐ‬
‫‪Activity 1‬‬ ‫‪Activity 2‬‬ ‫‪Private‬إﻟﻰ اﻟﻄﺮﻳﻘﺔ ﻛﺬﻟﻚ‬
‫ﺗﻤﺮﻳﺮﻫﺎ‬
‫‪Method 1‬‬ ‫‪Method 3‬‬ ‫ﺑﻌﺾ اﻟﻄﺮق إذا ﺗﻢ اﺳﺘﺪﻋﺎءﻫﺎ ﻓﺈﻧﻬﺎ ﺗﺮﺟﻊ ﻗﻴﻤﺔ ﻣﻌﻴﻨﺔ وﻫﺬا‬
‫‪Call‬‬
‫‪Arguments Method‬‬ ‫‪Param‬‬
‫)(‪4‬‬ ‫‪eters‬‬ ‫اﻟﻨﻮع ﻣﻦ اﻟﻄﺮق ﻳﺠﺐ أن ﻳﺤﺘﻮي ﻋﻠﻰ ﻧﻮع اﻟﺒﻴﺎﻧﺎت اﻟﻤﺮﺟﻌﺔ‪،‬‬
‫‪Method 2‬‬ ‫‪Method 4‬‬
‫وﻫﻨﺎك ﻃﺮق ﻻﺗﺤﺘﻮي ﻋﻠﻰ ﻗﻴﻢ ﻣﺮﺟﻌﺔ ﻓﻴﺠﺐ أن ﻳﻴﻜﻮن ﻧﻮع‬
‫‪Private‬‬ ‫‪Public‬‬ ‫اﻟﺒﻴﺎﻧﺎت اﻟﻤﺮﺟﻌﺔ ﻓﻴﻬﺎ ‪ void‬وﻣﻊ ذﻟﻚ ﻫﺬه اﻟﻄﺮﻳﻘﺔ ﻗﺪ ﺗﻐﻴﺮ ﻗﻴﻤﺔ‬
‫ﻣﺘﻐﻴﺮات ﻋﺎﻣﺔ ‪ global‬ﺑﺪاﺧﻠﻬﺎ‬
‫‪Access‬‬ ‫‪Returned‬‬ ‫‪Method‬‬ ‫‪Data‬‬ ‫‪Variable‬‬ ‫‪Data‬‬ ‫‪Variable‬‬
‫‪Modifier‬‬
‫ﻣﻌﺎﻣﻼت اﻟﻮﺻﻮل‬
‫‪Data type‬‬
‫ﻧﻮع اﻟﺒﻴﺎﻧﺎت‬
‫اﻟﻤﻌـــــﺎدة‬
‫‪name‬‬
‫اﺳﻢ اﻟﻄﺮﻳﻘﺔ‬
‫(‬ ‫‪type‬‬
‫ﻧﻮع اﻟﻤﺘﻐﻴﺮ‬
‫‪name‬‬ ‫‪type‬‬
‫اﺳﻢ اﻟﻤﺘﻐﻴﺮ‬
‫‪,‬‬ ‫‪name‬‬
‫ﻧﻮع اﻟﻤﺘﻐﻴﺮ‬ ‫اﺳﻢ اﻟﻤﺘﻐﻴﺮ‬
‫}{ )‬
‫‪Public‬‬ ‫‪int‬‬ ‫( ‪textToDisplay‬‬ ‫‪int‬‬ ‫‪number ,‬‬ ‫‪String‬‬ ‫‪text‬‬ ‫}{ )‬ ‫ﻣﺜﺎل‪:‬‬

‫‪17‬‬
‫اﺳﺘﺪﻋﺎء اﻟﻄﺮﻳﻘﺔ ‪CALLING A METHOD‬‬
‫**‪/‬‬
‫‪* Calculates the price of the order.‬‬ ‫ﻳﻔﻀﻞ داﺋﻤﺎ وﺿﻊ ﺷﺮح ﻟﻠﻄﺮﻳﻘﺔ ﻋﻠﻰ ﻃﺮﻳﻘﺔ‬
‫‪* @param addWhippedCream will check if whipped cream is clicked‬‬
‫‪* @param addChocolate will check if chocolate is clicked‬‬ ‫ﻣﻼﺣﻈﺎت وذﻛﺮ وﻇﻴﻔﺔ اﻟﻌﻮاﻣﻞ داﺧﻠﻬﺎ‬
‫‪* @return the total price in returned‬‬ ‫‪. Parameters‬وﻣﺎﻫﻲ اﻟﻘﻴﻤﺔ اﻟﺘﻲ ﺳﺘﺮﺟﻌﻬﺎ‬
‫‪*/‬‬ ‫ﻳﺘﻢ وﺿﻊ ﻋﻼﻣﺔ ‪ @param‬ﻗﺒﻞ ﺷﺮح اﻟﻌﺎﻣﻞ‬
‫{ )‪private int calculatePrice(boolean addWhippedCream, boolean addChocolate‬‬
‫;‪int basePrice = 5‬‬ ‫ﻟﻌﻤﻞ رﺑﻂ ﻟﻠﻤﻼﺣﻈﺔ ﺑﺎﻟﻌﺎﻣﻞ ﻓﻲ اﻟﻄﺮﻳﻘﺔ‬
‫;‪if (addWhippedCream) basePrice++‬‬ ‫ﻟﻴﺲ ﻫﻨﺎك داع ﻹرﺳﺎل ﺑﻴﺎﻧﺎت إﺿﺎﻓﻴﺔ ﻟﻦ‬
‫;‪if (addChocolate) basePrice += 2‬‬ ‫أﺳﺘﺨﺪﻣﻬﺎ داﺧﻞ اﻟﻄﺮﻳﻘﺔ‬
‫; ‪return 3* basePrice‬‬ ‫ﻫﻨﺎ ﺗﻢ اﺳﺘﺪﻋﺎء اﻟﻄﺮﻳﻘﺔ ووﺿﻊ ﻗﻴﻤﺘﻬﺎ ﻓﻲ‬
‫}‬ ‫ﻣﺘﻐﻴﺮ ﻣﻦ ﻧﻔﺲ ﻧﻮع اﻟﺒﻴﺎﻧﺎت اﻟﻤﺮﺟﻌﺔ ﻣﻦ‬
‫‪@Override‬‬
‫{ )‪protected void onCreate(Bundle savedInstanceState‬‬
‫اﻟﻄﺮﻳﻘﺔ ‪int = int‬‬
‫;)‪super.onCreate(savedInstanceState‬‬
‫;)‪setContentView(R.layout.activity_main‬‬ ‫إذا ﺗﻢ ﺗﻌﺮﻳﻒ ﻋﻮاﻣﻞ إدﺧﺎل ‪ Parameters‬ﺑﺈﺳﻢ‬
‫ﻣﺸﺎﺑﻪ ﻟﻤﺘﻐﻴﺮات ﻋﺎﻣﺔ ‪ Global Variables‬ﻓﺈن‬
‫;)‪int price = calculatePrice(true, true‬‬
‫}‬ ‫اﻷﻓﻀﻠﻴﺔ ﺗﻜﻮن ﻟﻠﻌﻮاﻣﻞ اﻟﻤﺪﺧﻠﺔ‬

‫ﺗﻢ ﺗﻨﻔﻴﺬ اﻷﻣﺮ ‪return‬‬ ‫‪2‬‬ ‫ﺗﻢ ﺗﻨﻔﻴﺬ ﺟﻤﻴﻊ اﻷﺳﻄﺮ اﻟﺒﺮﻣﺠﻴﺔ‬ ‫‪1‬‬ ‫ﻳﻨﺘﻬﻲ اﻟﺘﻌــــﺎﻣﻞ ﻣــﻊ‬
‫أﻳﻬﻤﺎ ﻳﺤﺪث ﻗﺒﻞ‬ ‫اﻟﻄﺮﻳﻘﺔ اﻟﻤﺴﺘﺪﻋﺎة إذا‬
‫ﺣﺪث ﺧﻄﺄ ﻣﺎ ﻓﻲ داﺧﻞ اﻟﻄﺮﻳﻘﺔ ‪Throw an excption‬‬ ‫‪3‬‬

‫ﻛﻠﻤﺔ ‪ void‬ﺗﻌﻨﻲ ﻋﺪم إرﺟﺎع ﻗﻴﻤﺔ ﻣﻦ اﻟﻄﺮﻳﻘﺔ‬ ‫اﻷﻣﺮ ;‪ return‬ﻏﻴﺮ ﺿﺮوري ﻷﻧﻪ ﻻ ﻳﺮﺟﻊ أي ﻗﻴﻤﺔ ﻣﻔﻴﺪة‬

‫ﺑﺎﻟﺘﻌﺎون ﻣﻊ اﻷﺳﺘﺎذ‪ :‬ﺣﺴﻦ ﻳﻮﺳﻒ‬ ‫ﺷﺮح ﻣﻠﻔﺎت و ﻣﺠﻠﺪات اﻧﺪروﻳﺪ اﺳﺘﺪﻳﻮ ‪Android Studio folder structure‬‬
‫‪@Hassan_Youssef_Tutor‬‬

‫وﻫﻮ ﻳﺤﺘﻮي ﻋﻠﻰ ﻣﻠﻒ ﺗﺴﺘﻄﻴﻊ‬ ‫أي ﻣﺠﻠﺪ ‪ Resources‬وﻫﻮ ﻋﺒﺎرة‬ ‫وﻫﻮ ﻋﺒﺎرة ﻋﻦ ﻣﺠﻠﺪ اﻟﺘﻄﺒﻴﻖ‬
‫ﻣﻦ ﺧﻼﻟﻪ ﺗﺤﺪﻳﺪ ﺻﻼﺣﻴﺎت‬ ‫ﻋﻦ ﻣﺠﻠﺪ اﻟﻤﺼﺎدر أو اﻟﻤﻮارد‬ ‫اﻟﺨﺎص ﺑﻚ و ﻫﻮ ﻳﺤﺘﻮي ﻋﻠﻰ‬
‫اﻟﺘﻄﺒﻴﻖ ﻛﻤﺎ ﺗﺴﺘﻄﻴﻊ ﺗﺤﺪﻳﺪ اول‬ ‫اﻟﺨﺎﺻﺔ ﺑﺎﻟﺘﻄﺒﻴﻖ و ﺑﺎﺧﺘﺼﺎر‬ ‫اﻟﻜﺜﻴﺮ ﻣﻦ اﻟﻤﻠﻔﺎت و اﻟﻤﺠﻠﺪات‬
‫ﻧﺎﻓﺬة ﺳﺘﻈﻬﺮ ﻟﻚ ﻋﻨﺪ ﻓﺘﺢ‬ ‫ﻳﺘﻀﻤﻦ ﺟﻤﻴﻊ اﻟﺼﻮر و‬ ‫اﻟﺨﺎﺻﺔ ﺑﺘﻄﺒﻴﻘﻚ‪ ،‬ﺣﻴﺚ ﻫﻨﺎ‬
‫اﻟﺘﻄﺒﻴﻖ اﻫﻢ ﺷﻲء ﻋﻠﻴﻚ ﺗﺬﻛﺮه‬ ‫اﻟﺼﻮﺗﻴﺎت و اﻟﻨﺼﻮص و اﻟﺜﻴﻢ و‬ ‫ﺳﺘﺠﺪ ﺟﻤﻴﻊ اﻻﻛﻮاد و اﻟﻤﺼﺎدر‬
‫ﻫﻨﺎ ﻫﻮ اﻧﻪ ﻓﻲ ﺣﺎل إﺿﺎﻓﺔ‬ ‫اﻟﺘﻲ ﺳﺘﻈﻬﺮ ﻓﻲ واﺟﻬﺔ‬
‫أﻛﺘﻔﺘﻲ ﺟﺪﻳﺪ ﻓﻲ ﻣﺸﺮوﻋﻚ‬ ‫اﻟﺘﻄﺒﻴﻖ ‪،‬و ﻳﺘﺄﻟﻒ ﻫﺬا اﻟﻤﺠﻠﺪ‬ ‫وﻫﻮ ﻳﺤﺘﻮي ﻋﻠﻰ ﻣﻠﻒ اﻟﺠﺎﻓﺎ‬
‫ﻋﻠﻴﻚ إﺿﺎﻓﺘﻪ ﻓﻲ ﻣﻠﻒ ‪Manifest‬‬ ‫ﻣﻦ ﻋﺪة ﻣﺠﻠﺪات ﻓﺮﻋﻴﺔ‬ ‫اﻟﺮﺋﻴﺴﻲ ‪ MainActivity.java‬وﻫﻮ‬
‫وﻫﻮ ﻳﺤﺘﻮي ﻋﻠﻰ اﻟﺼﻮر‬ ‫وﻫﻮ ﻳﺤﺘﻮي ﻋﻠﻰ اﻟﻤﺆﺛﺮات‬ ‫وﻫﺬا اﻟﻤﻠﻒ ﻳﺤﺘﻮي ﻋﻠﻰ اﻟﻜﻮد‬
‫اﻟﺘﻲ ﺳﻴﺘﻢ اﺳﺘﺨﺪاﻣﻬﺎ ﻓﻲ‬ ‫ﺳﻴﺘﻢ‬ ‫اﻟﺘﻲ‬ ‫اﻟﺤﺮﻛﻴﺔ‬ ‫اﻟﺒﺮﻣﺠﻲ و ﻛﻼس اﻻﻛﺘﻔﺘﻲ و اﻟﺘﻲ‬
‫اﻟﺘﻄﺒﻴﻖ ﺑﺎﻹﺿﺎﻓﺔ اﻟﻰ‬ ‫اﺳﺘﺨﺪاﻣﻬﺎ ﻓﻲ اﻟﺘﻄﺒﻴﻖ‬ ‫ﺳﻨﻜﺘﺐ ﺑﺪاﺧﻠﻬﺎ اﻷﻛﻮاد و اﻷواﻣﺮ‬
‫اﻟﺼﻮر و ﺧﻠﻔﻴﺔ اﻟﺘﻄﺒﻴﻖ…‬ ‫اﻟﺒﺮﻣﺠﻴﺔ ﺑﻠﻐﺔ اﻟﺠﺎﻓﺎ ﻟﻠﻌﻨﺎﺻﺮ‬
‫وﻫﻮ ﻳﺤﺘﻮي ﻋﻠﻰ اﻟﻘﻮاﺋﻢ‬ ‫اﻟﻤﻮﺟﻮدة ﻓﻲ ﻣﻠﻒ ‪activity_main.xml‬‬
‫اﻟﺨﺎﺻﺔ ﺑﻤﻠﻒ اﻟـ ‪XML‬‬ ‫اﻟﺘﻲ ﺳﻴﺘﻢ اﺳﺘﺨﺪاﻣﻬﺎ ﻓﻲ‬
‫ﻣﻠﻒ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ وﻫﺬا‬ ‫اﻟﺘﻄﺒﻴﻖ ﻟﻠﺘﻨﻘﻞ ﺑﻴﻦ ﺷﺎﺷﺎت‬ ‫وﻫﻮ ﻳﺤﺘﻮي ﻋﻠﻰ اﻟﻌﺪﻳﺪ ﻣﻦ‪:‬‬
‫اﻟﻤﻠﻒ ﻳﻌﺘﻤﺪ ﻋﻠﻰ ‪XML‬و‬ ‫اﻟﺘﻄﺒﻴﻖ وﺧﻴﺎراﺗﻪ اﻷﺧﺮى‬ ‫اﻟﻤﻠﻔﺎت و ﻟﻌﻞ ﻣـﻦ اﻫﻤﻬﺎ ﻣﻠﻒ‬
‫وﺗﺴﺘﺨﺪم ﻣﻠﻔﺎت ‪XML‬‬ ‫و اﻟﺬي‬ ‫اﻟـ‬
‫)‪Build.gradle(module:app‬‬
‫أﻳﻘﻮﻧﺎت‬ ‫ﻣﻠﻒ‬ ‫وﻫﻮ‬ ‫وﻫﻮ ﻳﺤﺘﻮي ﻋﻠﻰ ﻣﻠﻒ‬ ‫ﻳﺘﻀﻤﻦ أﻗﻞ إﺻﺪار ﺳﻴﻌﻤﻞ ﻋﻠﻴﻪ‬
‫اﻟﺘﻄﺒﻴﻖ ﻛﻤﺎ ﻳﻈﻬﺮ ﻓﻲ‬ ‫اﻟﻘﻴﻢ و اﻟﻨﺼﻮص ﻣﻠﻒ اﻟﺜﻴﻢ‬ ‫ﺗﻄﺒﻴﻘﻚ و رﻗﻢ اﻹﺻﺪار و إﺳﻢ‬
‫ﻣﺘﺠﺮ اﻟﺘﻄﺒﻴﻘﺎت أو ﻋﻨﺪ‬ ‫اﻟﺨﺎﺻﺔ ﺑﺎﻟﺘﻄﺒﻴﻖ ﺑﺎﻹﺿﺎﻓﺔ‬ ‫اﻹﺻﺪار اﻟﺨﺎص ﺑﺘﻄﺒﻴﻘﻚ‬
‫ﺗﻨﺰﻳﻞ اﻟﺘﻄﺒﻴﻖ ﻓﻲ اﻟﺠﻬﺎز‬ ‫اﻟﻰ ﻣﻠﻒ ﻗﻴﻢ اﻻﻟﻮان‬

‫‪18‬‬
‫ﻓﺎﺋﺪة ﻓﺼﻞ اﻟﻜﻮدات ‪ java‬ﻋﻦ ‪ Res‬أﻧﻪ ﻳﻤﻜﻨﻨﺎ ﺗﻮﻓﻴﺮ ﻣﻮارد ﺑﺪﻳﻠﺔ ﻟﺠﻌﻞ اﻟﺘﻄﺒﻴﻖ ﻳﺒﺪو أﻓﻀﻞ ﺑﺈﺧﺘﻼف اﻷﺟﻬﺰة‪ ،‬ﻓﻠﻮ أردﻧﺎ‬
‫ﺻﻮر وأﻳﻘﻮﻧﺎت ﻟﺸﺎﺷﺎت أﻛﺒﺮ‪ ،‬ﻳﻤﻜﻨﻨﺎ ﺗﻮﻓﻴﺮﻫﺎ ﻓﻲ ﻣﺠﻠﺪ اﻟﺮﺳﻮﻣﻴﺎت ‪ drawable‬وﺳﻴﺘﺨﺎر اﻟﺘﻄﺒﻴﻖ اﻷﺣﺠﺎم اﻟﻤﻨﺎﺳﺒﺔ‪.‬‬
‫ﻟﻮ أردﻧﺎ ﺗﺮﺟﻤﺔ اﻟﻨﺼﻮص إﻟﻰ ﻟﻐﺔ أﺧﺮى ﻓﺄﻧﻪ ﺳﻴﻜﻮن ﺳﻬﻼ إذا ﻣﺎ ﺗﻢ وﺿﻊ اﻟﻨﺼﻮص ﻓﻲ ﻣﻠﻒ ‪ strings.xml‬وﻣﻦ ﺛﻢ‬
‫ﺗﺮﺟﻤﺘﻬﺎ واﻟﺘﻄﺒﻴﻖ ﻳﺨﺘﺎر اﻟﻠﻐﺔ اﻟﻤﻨﺎﺳﺒﺔ ﺑﺤﺴﺐ ﻟﻐﺔ ﺟﻬﺎز اﻟﻤﺴﺘﺨﺪم‪.‬‬

‫رﻗﻢ اﻟﺘﻌﺮﻳﻒ اﻟﺨﺎص ﺑﺎﻟﻤﻮرد ‪RESOURCE ID NUMBER‬‬

‫ﻋﻨﺪﻣﺎ ﻳﺘﻢ ﺑﻨﺎء اﻟﺘﻄﺒﻴﻖ داﺧﻞ اﻷﻧﺪرﻳﻮد اﺳﺘﻮدﻳﻮ ﻓﺈن ﻫﻨﺎك أداة ﺗﺴﻤﻰ ‪ AAPT‬ﺗﻘﻮم ﺑﺘﻮﻟﻴﺪ ﺻﻨﻒ اﺳﻤﻪ ‪R.java‬‬
‫ﻳﺤﺘﻮي ﻫﺬا اﻟﺼﻨﻒ ﻋﻠﻰ أرﻗﺎم ﻣﻌﺮﻓﺔ ﻟﻜﻞ اﻟﻤﻮارد اﻟﻤﺤﺘﻮاه ﻓﻲ ﻣﺠﻠﺪ ‪ Res‬ﺗﺘﻢ أرﺷﻔﺘﻬﺎ ﻓﻲ ﻫﺬا اﻟﻤﻠﻒ ﻟﻴﺴﻬﻞ‬
‫اﻹﺷﺎرة إﻟﻰ اﻟﻤﻮارد ﻋﻦ ﻃﺮﻳﻖ رﻗﻢ ﺗﻌﺮﻳﻔﻬﺎ‬

‫‪/Res‬‬ ‫‪R.java‬‬ ‫‪AAPT: Android Asset Packaging Tool‬‬


‫‪image.jpg‬‬ ‫;‪public static final int image = 0x7f010000‬‬
‫‪icon.gif‬‬
‫‪views‬‬ ‫‪AAPT‬‬ ‫;‪public static final int icon = 0x7f010233‬‬
‫;‪public static final int text1 = 0x7f010233‬‬
‫ﻟﻠﻤﻌﻠﻮﻣﺎت أﻛﺜﺮ ﻋﻦ اﻷداة ‪ AAPT‬ﻳﺮﺟـﻰ‬
‫‪strings‬‬ ‫‪..‬‬ ‫زﻳﺎرة اﻟﻤﻮﻗﻊ ‪https://elinux.org/Android_aapt‬‬
‫‪colors‬‬ ‫‪.‬‬
‫‪...‬‬
‫‪.‬‬

‫ﺗﺮﺗﻜﺰ ﺻﻴﻐﺔ اﺳﺘﺨﺪام اﻟﻤﻌﺮف ﻓﻲ اﻟﻜﻮدات اﻟﺒﺮﻣﺠﻴﺔ ﻋﻠﻰ ﻧﻮع اﻟﻤﻮرد‪ ،‬ﻣﺜﻼ ﻟﻜﻞ اﻟﻤﻮارد اﻟﺮﺳﻮﻣﻴﺔ ﻧﺴﺘﺨﺪم ﻫﺬا‬
‫اﻟﻨﻤﻂ اﺳﻢ اﻟﺼﻮرة‪ R.drawable.‬ﻣﺜﺎل‪ R.drawable.coder :‬واﺳﻢ اﻟﺼﻮرة ﻫﻨﺎ ﻳﻜﺘﺐ ﻣﻦ دون ﻛﺘﺎﺑﺔ إﻣﺘﺪاد اﻟﺼﻮرة‬
‫وﻟﻜﻞ اﻟﻨﺼﻮص اﻟﻤﻜﺘﻮﺑﺔ ﻓﻲ ﻣﻠﻒ ‪ strings.xml‬ﻳﺘﻢ اﻹﺷﺎرة إﻟﻴﻬﺎ ﻫﻜﺬا اﺳﻢ اﻟﻮﺳﻢ ‪R.string.‬‬
‫)داﺧﻞ اﻟﻤﻠﻒ ‪(strings.xml‬‬ ‫)داﺧﻞ ﻣﻠﻒ اﻟﺠﺎﻓﺎ(‬ ‫ﻣﺜﺎل‪:‬‬
‫>‪<string name="title">welcome</string‬‬ ‫‪R.string.title‬‬

‫ﻳﻤﻜﻦ اﻹﺷﺎرة إﻟﻰ اﻟﻤﻮارد ﻛﺬﻟﻚ ﻓﻲ ﻣﻠﻔﺎت واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ ‪ XML‬ﻓﺄداة ﺑﻨﺎء ﻣﻠﻔﺎت ‪ XMLC‬واﺳﻤﻬﺎ ﺗﺴﺘﺨﺪم ﻫﺬه‬
‫اﻟﻄﺮﻳﻘﺔ ﻓﻲ اﻹﺷﺎرة إﻟﻰ اﻟﻤﻮارد اﺳﻢ اﻟﺼﻮرة ‪ @drawable/‬ﻣﺜﺎل‪@drawable/coder :‬‬
‫‪@string/title‬‬ ‫اﺳﻢ اﻟﻮﺳﻢ ‪ @string/‬ﻣﺜﺎل‪:‬‬
‫‪XMLC - Extensible Markup Language Compiler‬‬

‫ﻣﻘﺎرﻧﺔ اﺳﺘﺨﺪام اﻟﻤﻮارد ﺑﻴﻦ ‪ XML‬و ‪JAVA‬‬

‫‪19‬‬
‫ ؟‬JAVA ‫ إﻟﻰ‬XML ‫ﻣﺎ اﻟﺬي ﻳﺤﺼﻞ ﻣﻦ‬
<LinearLayout
..
android:layout_width="match_parent" OnCreate() {
android:layout_height="match_parent">
...
<TextView setContentView(R.layout.activity_main);
android:layout_width="wrap_content"
android:layout_height="wrap_content" ...
android:text="Hello World!" /> MainActivity
<LinearLayout }
android:layout_width="match_parent"
android:layout_height="match_parent"> ‫ﻳﺸﻴﺮ ﻫﺬا اﻟﺴﻄﺮ إﻟﻰ ﻣﻠﻒ‬ 4 ‫ﻳﻨﻔــــﺬ اﻟﺘﻄﺒﻴــــﻖ أواﻣــــﺮ‬ 3 Initialized
<TextView
android:layout_width="wrap_content" ‫اﻟﻤﻮارد ﻟﻌﺮض ﻋﻨﺎﺻﺮه ﻓﻲ‬ ‫ ﺑﺎﻟﺘﺮﺗﺘﺐ‬OnCreate() ‫اﻟﻄﺮﻳﻘﺔ‬
android:layout_height="wrap_content"
android:text="Hello World!" /> ‫ﺷﺎﺷﺔ اﻟﻨﺸـﺎط‬ ‫ﻣـﻦ اﻷﻋﻠﻰ إﻟــﻰ اﻷﺳﻔـــﻞ‬
<Button
android:layout_width="wrap_content" 1
android:layout_height="wrap_content"
android:text="Price"/>
2
<Button ‫ﻳﺒﺪأ اﻟﺘﻄﺒﻴﻖ اﻟﻨﺸـــﺎط‬ ‫ﻳﻀﻐﻂ اﻟﻤﺴﺘـــﺨﺪم‬
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Order" ‫اﻟﺮﺋﻴﺴﻲ ﻓﻲ اﻟﻮاﺟﻬﺔ‬ ‫ﻋﻠﻰ أﻳﻘﻮﻧﺔ اﻟﺘﻄﺒﻴﻖ‬
android:OnClick="submitOrder"/>

</LinearLayout> Parsing
MainActivity

‫ ﺑﻴﺎﻧﺎت‬Parsing ‫ ﻳﺘﻢ ﺗﺤﻠﻴﻞ‬5


lorem ipsum dolor sit amet consectetur adipiscing elit
curabitur eget pretium tortor eget accumsan diam

LinearLayout ‫ اﻷوﺳﻤﺔ إﻟﻰ‬Inflate ‫ﻳﺘﻢ ﺗﺤﻮﻳﻞ‬ 6 lorem ipsum dolor sit amet consectetur adipiscing elit
curabitur eget pretium tortor eget accumsan diam

‫ وﺗﻌﺮف ﻋﻠــﻰ‬XML ‫ﻣﻠﻒ‬ ‫ﻋﻨﺎﺻﺮ ﻋﺮض وﺛﻢ ﻋﺮﺿﻬﺎ‬


lorem ipsum dolor sit amet consectetur adipiscing elit
curabitur eget pretium tortor eget accumsan diam

lorem ipsum dolor sit amet consectetur adipiscing elit


curabitur eget pretium tortor eget accumsan diam

‫ ﺑﺎﻟﺘﺮﺗﻴـﺐ‬TAGS ‫اﻷوﺳﻤـﺔ‬ TextView LinearLayout ‫ﻓﻲ ﺷﺎﺷﺔ اﻟﻨﺸﺎط اﻟﺬي‬


lorem ipsum dolor sit amet consectetur adipiscing elit
curabitur eget pretium tortor eget accumsan diam

‫ﻣــﻦ اﻷﻋﻠﻰ إﻟﻰ اﻷﺳﻔﻞ‬


lorem ipsum dolor sit amet consectetur adipiscing elit
curabitur eget pretium tortor eget accumsan diam

‫ﻳﻌﺮﺿﻪ اﻟﻤﺴﺘﺨﺪم‬
TextView Button Button

JAVA OBJECTS ‫ﻛﺎﺋﻨﺎت ﺟﺎﻓﺎ‬

Methods ‫ واﻟﻄﺮق‬State/Attribute/Field ‫ اﻟﺤﺎﻟﺔ‬: ‫ ﻓﻲ اﻟﺠﺎﻓﺎ ﻳﺘﻀﻤﻦ ﻧﻮﻋﻴﻦ ﻣﻦ اﻟﺒﻴﺎﻧﺎت‬object ‫ﻛﻞ ﻛﺎﺋﻦ‬


Template (‫)ﻗﺎﻟﺐ‬
TextView.class
TextView.class ‫ ﻳﻘﻮم اﻟﺼﻨﻒ اﻟﺨﺎص ﺑﻌﺮض اﻟﻨﺺ‬:‫ﻣﺜﺎل‬
‫ﺑﺤﻔــﻆ ﺣــﺎﻻت اﻟﻜﺎﺋــﻦ وﻫﻮ ﻳﻌﻤـﻞ ﻛﻘﺎﻟﺐ وﻫﺬا‬
textView1 textView2 ‫ﻳﻌﻨﻲ أن ﻛﻞ ﻛﺎﺋﻦ ﻋﺮض ﻧﺺ ﻟﻪ ﺣﺎﻻﺗﻪ وﻳﺘﻢ ﺗﻐﻴﻴﺮﻫﺎ‬
“Price”
textView2
“Hello”
“Order” setText(”Hello”) :‫ ﻣﺜـــﺎل‬,‫ﺑﺎﺳﺘﺨﺪام اﻟﻄﺮق اﻟﻤﻀﻤﻨﺔ‬
Instance Instance Instance

ImageView.class ‫ ﻳﻘﻮم اﻟﺼﻨﻒ اﻟﺨﺎص ﺑﻌﺮض اﻟﺼﻮرة‬:‫ﻣﺜﺎل‬


‫ﺑﺤﻔــﻆ ﺣــﺎﻻت اﻟﺼﻮرة ﻣﺜﻞ اﺳﻢ اﻟﺼﻮرة اﻟﻤﻌﺮوﺿﺔ‬
‫وﻃﺮﻳﻘﺔ ﻋﺮﺿﻬﺎ وأﻳﻀﺎ ﺗﺴﺘﺨﺪم اﻟﻄﺮق اﻟﻤﻀﻤﻨﺔ‬
setImage(”fish”) :‫ ﻣﺜـــﺎل‬,‫ﻟﺘﻐﻴﻴﺮ ﻫﺬه اﻟﺤﺎﻻت‬
setScaleType(”centerCrop”)

Constructor ‫ﻫﻨﺎك ﻃﺮﻳﻘﺔ ﻣﻀﻤﻨﺔ داﺧﻞ أﺻﻨﺎف اﻟﻜﺎﺋﻨﺎت ﺗﺴﺘﺨﺪم ﻟﻌﻤﻞ ﻧﺴﺦ ﻟﻠﺼﻨﻒ اﻟﺮﺋﻴﺴﻲ اﻟﻘﺎﻟﺐ وﺗﺴﻤﻰ‬

Constructor ‫ ﻋﻤﻞ ﻛﺎﺋﻦ ﺟﺪﻳﺪ ﺑﺈﺳﺘﺨﺪام اﻟـ‬1


Initial Value ‫اﻟﻘﻴﻤﺔ اﻟﻤﺒﺪﺋﻴﺔ‬
Object Data type Variable Name
‫ﻧﻮع اﻟﺒﻴﺎﻧﺎت اﻟﻜﺎﺋﻦ‬ ‫اﺳﻢ اﻟﻤﺘﻐﻴﺮ‬ = new Object Data type
‫ﻧﻮع اﻟﺒﻴﺎﻧﺎت اﻟﻜﺎﺋﻦ‬ (input args) ;
Constructor
TextView priceTextView = new TextView(context);
ImageView coffeImageView = new ImageView(context);
Button submitOrderButton = new Button(context);
CatView sleepyCatView = new CatView(”Tiger”);

20
‫ﺗﺎﺑﻊ‬ ‫ﻛﺎﺋﻨﺎت ﺟﺎﻓﺎ ‪JAVA OBJECTS‬‬

‫ﻛﻤﺎ ﺗﻢ اﻟﺘﻮﺿﻴﺢ ﻓﺈن اﻟـ ‪ constructor‬ﻫﻲ ﻃﺮﻳﻘﺔ أﺳﺎﺳﻴﺔ ﻣﻮﺟﻮدة ﻓﻲ ﺻﻨﻒ اﻟﻜﺎﺋﻦ وﻳﻌﺘﻤﺪ ﻧﻮع ﺑﻴﺎﻧﺎت ﻣﻌﺎﻣﻼت‬
‫اﻹدﺧﺎل )‪ input Arguments (args‬ﻋﻠﻰ ﻧﻮع اﻟﺒﻴﺎﻧﺎت ﻓﻲ اﻟﻄﺮﻳﻘﺔ اﻷﺳﺎﺳﻴﺔ‬
‫اﻟﻤﺘﻐﻴﺮ ﻟﻤﻌﺎﻣﻼت اﻹدﺧﺎل اﻟﻤﺴﺘﺨﺪم ﻓﻲ اﻷﻣﺜﻠﺔ اﻟﺴﺎﺑﻘﺔ ﻫﻮ ﻣﻦ ﻧﻮع ‪ context‬وﻫﻮ ﻳﺤﺪد ﻟﻠـ ‪ constructor‬اﻟﻨﺸﺎط أو‬
‫اﻹﻃﺎر اﻟﺬي ﺳﻴﺘﻢ إﻧﺸﺎء ‪ instance‬ﻣﻦ اﻟﻜﺎﺋﻦ ﻓﻴﻪ‬
‫‪ 2‬ﻋﻤﻞ ﻛﺎﺋﻦ ﺟﺪﻳﺪ ﺑﺈﺳﺘﺨﺪام ﻃﺮﻳﻘﺔ اﻟﻤﺼﻨﻊ ‪factory method‬‬
‫‪Initial Value‬‬ ‫اﻟﻘﻴﻤﺔ اﻟﻤﺒﺪﺋﻴﺔ‬
‫‪Object Data type‬‬ ‫‪Variable Name‬‬
‫ﻧﻮع اﻟﺒﻴﺎﻧﺎت اﻟﻜﺎﺋﻦ‬ ‫اﺳﻢ اﻟﻤﺘﻐﻴﺮ‬ ‫=‬ ‫‪Object Data type‬‬
‫ﻧﻮع اﻟﺒﻴﺎﻧﺎت اﻟﻜﺎﺋﻦ‬ ‫‪.‬‬ ‫‪Factory Method Name‬‬
‫اﺳﻢ ﻃﺮﻳﻘﺔ اﻟﻤﺼﻨﻊ‬ ‫)‪(input args‬‬ ‫;‬
‫‪Factory Method Name‬‬

‫;)‪MediaPlayer player = MediaPlayer.create(context, R.raw.song‬‬


‫;)‪Toast toastMessage = Toast.makeText(context, “Hi”, duration‬‬
‫ﺗﺴﺘﺨﺪم ﻃﺮﻳﻘﺔ اﻟﻤﺼﻨﻊ ﻟﻠﻮﺻﻮل إﻟﻰ اﻟﻄﺮق اﻟﻌﺎﻣﺔ ‪ public‬اﻟﻤﻮﺟﻮدة ﻓﻲ ﺻﻨﻒ اﻟﻜﺎﺋﻦ ﻣﻦ دون اﻟﺤﺎﺟﺔ ﻹﺳﺘﺨﺪام‬
‫اﻟـ ‪constructor‬‬
‫ﻳﺠﺐ أن ﺗﻜﻮن أﻧﻮاع اﻟﺒﻴﺎﻧﺎت ﻟﻠﻤﺘﻐﻴﺮات ﻣﺘﺸﺎﺑﻬﺔ ﻗﺒﻞ ﻋﻼﻣﺔ = وﺑﻌﺪﻫﺎ‪ ،‬ﻣﺜﺎل‪:‬‬
‫;)‪TextView priceTextView = findViewById(R.id.price‬‬
‫‪ 2‬وﻫﻨﺎ ﻧﻮع ﺑﻴﺎﻧﺎت‬ ‫‪ 1‬ﻫﺬه اﻟﻄﺮﻳﻘﺔ ﻣﻮﺟﻮدة ﻓﻲ اﻟﻜﻼس ‪ AppCompatActivity‬واﻟﺬي ﻳﺮﺛﻪ اﻟﻜﻼس‬
‫اﻟﻜﺎﺋﻦ ﻣﺨﺘﻠﻒ‬
‫أو اﻟﻨﺸﺎط اﻟﺤﺎﻟﻲ وﺗﻘﻮم ﺑﺎرﺟﺎع ﻛﺎﺋﻦ ﻣﻦ ﻧﻮع ‪View‬‬
‫‪ 3‬وﻟﻜﻦ ﻷن ﻧﻮع اﻟﺼﻨﻒ ‪TextView‬ﻣﻮروث ﻣﻦ اﻟﺼﻨﻒ ‪View‬ﻓﻴﻤﻜﻨﻨﺎ ﺗﺤﻮﻳﻞ اﻟﻜﺎﺋﻦ اﻟﺬي ﺗﻘﻮم ‪ findViewById‬ﺑﺈرﺟﺎﻋﻪ‬
‫إﻟﻰ ﻛﺎﺋﻦ ﻧﺺ ﺑﺈﺳﺘﺨﺪام ‪ casting‬ﻓﺘﺼﺒﺢ ;)‪TextView priceTextView = (TextView) findViewById(R.id.price‬‬

‫ﺗﺴﺘﺨﺪم ﻟﺘﺤﺪﻳﺪ أن اﻟﻄﺮﻳﻘﺔ اﻟﻤﺴﺘﺨﺪﻣﺔ ﻟﻦ ﻳﺘﻢ ﺗﻮرﻳﺜﻬﺎ ﻣﻦ اﻟﺼﻨﻒ‪ Class‬اﻷﺳﺎﺳﻲ ﺑﻞ ﺳﻴﺘﻢ ﺗﻌﺮﻳﻒ ﻃﺮﻳﻘﺔ‬
‫‪@override‬‬
‫ﺟﺪﻳﺪة ﺑﻨﻔﺲ اﻹﺳﻢ ﻣﻊ إﺿﺎﻓﺔ ﻣﺤﺘﻮﻳﺎت أﺧﺮى ﻏﻴﺮ اﻷﺳﺎﺳﻴﺔ‬

‫أﺳﻠﻮب اﻟﺘﻮرﻳﺚ ‪INHERITANCE‬‬

‫ﻓﻜﺮة اﻟﻮراﺛﺔ ﺑﺴﻴﻄﺔ‪ ,‬ﻟﻜﻦ ﻓﺎﺋﺪﺗﻬﺎ ﻗﻮﻳﺔ ﺟﺪاً‪ .‬ﻓﻤﺜﻼً إذا‬


‫ﻛﻨﺖ ﺗﺮﻳﺪ إﻧﺸﺎء ﺻﻨﻒ ﺟﺪﻳﺪ و ﻻﺣﻈﺖ أﻧﻪ ﻳﻮﺟﺪ ﺻﻨﻒ‬
‫ﺟﺎﻫﺰ ﻳﺤﺘﻮي ﻋﻠﻰ ﻛﻮدات ﻗﺪ ﺗﻔﻴﺪك ﻳﻤﻜﻨﻚ اﺳﺘﻐﻼﻟﻬﺎ‬
‫ﺑﺪل ﻛﺘﺎﺑﺘﻬﺎ ﻣﻦ اﻟﺼﻔﺮ‪ ,‬أي ﻳﻤﻜﻨﻚ ﺟﻌﻞ اﻟﺼﻨﻒ اﻟﺬي‬
‫ﻗﻤﺖ ﺑﺘﻌﺮﻳﻔﻪ ﻳﺮث ﻫﺬا اﻟﺼﻨﻒ‪ ,‬و ﺑﻌﺪﻫﺎ ﻳﻤﻜﻨﻚ‬
‫إﺳﺘﺨﺪام ﺟﻤﻴﻊ اﻟﻤﺘﻐﻴﺮات و اﻟﺪوال اﻟﺘﻲ ورﺛﻬﺎ اﻟﺼﻨﻒ‬
‫اﻟﺠﺪﻳﺪ ﻣﻦ اﻟﺼﻨﻒ‪.‬‬

‫ﻓﻲ اﻟﻨﺸﺎط ﻧﻼﺣﻆ ﻓﻲ اﻷﻋﻠﻰ ﻋﺎدة ﻣﻜﺘﻮب‬


‫ﻓﺎﻟﻤﻘﺼﻮد أن اﻟﻨﺸﺎط ‪ MainActivity‬ﺳﻴﺮث‬
‫اﻟﻤﺘﻐﻴﺮات واﻟﺪوال وﻣﺜﺎل ذﻟﻚ ﻫﺬه اﻟﻄﺮﻳﻘﺔ‬
‫ﻣﻮﺟﻮدة داﺧﻞ اﻟﻜﻼس اﻟﻤ َﻮ ِرث ‪AppCompatActivity‬‬

‫‪21‬‬
‫اﻟﺨﻄﻮط اﻟﺤﻤﺮاء ﻓﻲ اﻟﺘﺼﻤﻴﻢ ‪RED LINES‬‬
‫ﻳﺘﻢ اﺳﺘﺨﺪام ﺑﻴﺎﻧﺎت اﻟﺨﻄﻮط اﻟﺤﻤﺮاء ﻣﻦ ﻗﺒﻞ ﻣﻄﻮري اﻷﻧﺪرﻳﻮد ﻟﺘﻨﺴﻴﻖ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ‬
‫اﺳﺘﻨﺎدا ﻋﻠﻴﻬﺎ‪ ،‬ﻓﻴﺘﻢ ﺗﺤﺪﻳﺪ ﺣﺠﻢ اﻟﺨﻂ‪ ،‬اﻷﻟﻮان‪ ،‬اﻟﻬﻮاﻣﺶ‪ ،‬واﻟﺴﺘﺎﻳﻞ وﻛﻞ اﻟﺒﻴﺎﻧﺎت اﻟﺨﺎﺻﺔ‬
‫اﻟﺘﻲ ﺗﺘﺤﻜﻢ ﻓﻲ ﻣﻈﻬﺮ اﻟﺘﻄﺒﻴﻖ‬

‫ﻳﻤﻜﻦ ﺗﻔﻌﻴﻞ ﺧﺎﺻﻴﺔ ‪ Red Lines‬ﻹﻇﻬﺎر اﻟﺨﻄﻮط اﻟﺤﻤﺮاء ﻓﻲ ﺟﻬﺎز اﻷﻧﺪرﻳﻮد اﻟﺨﺎص ﺑﻚ‬
‫ﺑﺘﻔﻌﻴﻞ ﺧﻴﺎر إﻇﻬﺎر ﺣﺪود اﻟﺘﺨﻄﻴﻂ ‪ Show layout boundries‬واﻟﻤﻮﺟﻮدة ﻓﻲ ﺧﻴﺎرات اﻟﻤﻄﻮر‬
‫ﻛﻤﺎ ﻓﻲ اﻟﺼﻮرة‬

‫ﻋﻨﺼﺮ ﺗﺨﻄﻴﻂ اﻟﻌﺮض ‪SCROLL VIEW‬‬


‫‪ScrollView‬‬
‫>‪<ScrollView‬‬
‫‪LinearLayout‬‬ ‫وﻫﻮ ﻋﻨﺼﺮ ﻋﺮض ﻣﻮرث ﻣﻦ ‪ ViewGroup‬ﻳﺴﺘﺨﺪم ﻟﺠﻌﻞ اﻟﻌﻨﺎﺻﺮ‬
‫‪View‬‬ ‫>‪<LinearLayout‬‬ ‫واﻟﻜﺎﺋﻨﺎت داﺧﻠﻪ ﻳﻤﻜﻦ ﺳﺤﺒﻬﺎ‪ ،‬وﻫﻮ ﻳﻘﺒﻞ ﻋﻨﺼﺮ ﻋﺮض اﺑﻦ واﺣﺪ‬
‫‪View‬‬ ‫ﺗﺤﺘﻪ ﻓﻘﻂ‪ ،‬ﺑﻤﻌﻨﻰ ﻣﺜﻼ ﻻ ﻳﻤﻜﻦ وﺿﻊ زر وﻋﻨﺼﺮ ﻋﺮض ﻧﺺ ﻣﻊ ﺑﻌﺾ‬
‫>‪<TextView/‬‬
‫‪View‬‬ ‫ﺗﺤﺘﻪ ﻣﺒﺎﺷﺮة ﻟﻜﻦ ﻳﻤﻜﻦ وﺿﻌﻬﻤﺎ داﺧﻞ ﻋﻨﺼﺮ ﺗﺨﻄﻴﻂ ‪ ViewGroup‬آﺧﺮ‬
‫>‪<Button/‬‬
‫‪View‬‬ ‫‪،‬ﺛﻢ وﺿﻊ ﻫﺬا اﻟﺘﺨﻄﻴﻂ ﺗﺤﺖ اﻟـ ‪ Child View‬ﻣﺒﺎﺷﺮة‬
‫‪View‬‬ ‫>‪</LinearLayout‬‬

‫>‪</ScrollView‬‬

‫‪IMPOSTER‬‬ ‫اﻹﺣﺘﻴﺎلاﻟﻌﺮض ‪VIEW‬‬


‫‪SCROLLSYNDROME‬‬ ‫ﻣﺘﻼزﻣﺔﺗﺨﻄﻴﻂ‬
‫ﻋﻨﺼﺮ‬
‫ﻟﻴﺲ اﻟﻤﻬﻢ أن ﺗﻜﻮن اﻷﻓﻀﻞ‪ ،‬ﻣﺎ ﻳﻬﻢ ﻫﻮ أن ﺗﻜﻮن‬ ‫ﻟﻤﺮﺣﻞ ﺗﺸﻌﺮ أﻧﻚ ﻟﻦ‬ ‫ﻓﻲ رﺣﻠﺘﻚ ﻟﺘﻌﻠﻢ اﻟﺒﺮﻣﺠﺔ ﺗﻘﺪ ﺗﺼﻞ‬
‫‪ViewGroup‬‬
‫اﻟﻴﻮم أﻓﻀﻞ ﻣﻤﺎ ﻛﻨﺖ ﻋﻠﻴﻪ ﺑﺎﻷﻣﺲ‬ ‫ﺗﺴﺘﻄﻴﻊ اﻟﻤﻮاﺻﻠﺔ وأﻧﻚ ﻗﺪ ﺗﻔﺸﻞ ﻟﻜﻦ اﻋﻠﻢ أﻧﻪ ﻗﺪ‬
‫اﻹﺑﺪاع ﻋﻨﺪي ﻫﻮ أن ﺗﺨﻔﻖ ﺑﺸﻜﻞ ﻣﺘﺘﺎل ﺣﺘﻰ‬ ‫ﻳﺤﺼﻞ اﻟﻔﺸﻞ ﻋﻨﺪﻣﺎ ﺗﺨﺎﻃﺮ ﻟﻜﻦ اﻟﻤﺨﺎﻃﺮة ﻣﻬﻤﺔ ﻟﻠﻨﺠﺎح‬
‫‪ ViewGroup‬ﺗﻨﺠﺢ ﻓﻲ ﻓﻌﻠﻬﺎ‪- .‬ﺳﻴﺚ ﺟﻮدﻳﻦ‬
‫رؤﻳﺔ اﻟﺠﺎﻧﺐ اﻟﻤﺸﺮق ﻣﻦ اﻟﻔﺸﻞ واﻟﻌﻤﻞ ﻋﻠﻰ ﺗﺤﻮﻳﻠﻪ‬
‫‪Child View‬‬ ‫إﻟﻰ ﻧﺠﺎح‬
‫اﻷﺳﺮار اﻟﺨﻤﺴﺔ ﻟﻠﻨﺠﺎح ‪ :‬اﻟﺘﺮﻛﻴﺰ‪ ،‬اﻟﺘﻤﻴﺰ‪ ،‬اﻟﺘﻨﻈﻴﻢ‪،‬‬
‫‪.‬اﻟﺘﻄﻮﻳﺮ‪ ،‬واﻟﺘﻮاﺻﻞ‬ ‫اﻟﺘﻨﻈﻴﻢ ﺣﻘﺎ ﻣﻬﻢ‪ ،‬ﻣﻦ دون ﺗﻨﻈﻴﻢ ﻟﻦ ﺗﻨﺠﺰ ﻋﻤﻞ واﺣﺪ‬
‫وﻟﻜﻦ ﻣﻊ اﻟﺘﻨﻈﻴﻢ ﺑﺎﺳﺘﻄﺎﻋﺘﻚ إﻧﺠﺎز اﻟﻌﺸﺮات ﻣﻦ اﻷﻋﻤﺎل‬

‫ﺟﺎﻓﺎ ‪MINUS NUMBERS IN JAVA‬‬ ‫ﺗﺨﻄﻴﻂﻓﻲ‬


‫اﻟﻌﺮض‬ ‫ﻋﻨﺼﺮ اﻟﺴﺎﻟﺒﺔ‬
‫اﻷرﻗﺎم‬

‫ﻧﺘﺤﺪث ﻋﻦ ﻣﻮﺿﻮع أﻧﻮاع ﺑﻴﺎﻧﺎت اﻟﻤﺘﻐﻴﺮات ﻣﻦ ﻧﻮع رﻗﻢ ‪ int, float, long, ....‬ﻧﻨﺒﻪ أﻧﻪ ﻻ ﻳﻮﺟﺪ ﻧﻮع ﺑﻴﺎﻧـــﺎت ﺟﺎﻓـﺎ‬
‫اﻋﺘﻴﺎدي ‪ primitive‬ﻳﻘﺒﻞ ﻓﻘﻂ أرﻗﺎم ﻣﻮﺟﺒﺔ‪ ،‬ﺑﻞ ﺟﻤﻴﻌﻬﺎ ﺗﻘﺒﻞ اﻟﻤﻮﺟﺐ واﻟﺴﺎﻟﺐ‪ ،‬ﻟﻜﻦ إذا اﺣﺘﺠﻨﺎ ﻓﻘﻂ إﻟﻰ أرﻗﺎم‬
‫ﻣﻮﺟﺒﺔ ﻓﻴﻤﻜﻨﻨﺎ اﻟﺘﺤﻜﻢ ﻓﻲ ﺗﺪﻓﻖ اﻟﺒﻴﺎﻧﺎت ‪ Control Flow‬ﻋﻦ ﻃﺮﻳﻖ اﻟﺠﻤﻠﺔ اﻟﺸﺮﻃﻴﺔ ‪If / else Statment‬‬
‫{ )‪if (quantity == 1‬‬ ‫ﺳﻴﺘﻜﻔﻞ ﻫﺬا اﻟﺴﻄﺮ ﺑﻌﺪم‬
‫اﻟﻮﺻﻮل إﻟﻰ اﻷﺳﻄﺮ أﺳﻔﻠﻪ‬
‫ﻓﺮﺿﺎ ﻛﺎن ﻟﺪﻳﻨﺎ ﻣﺘﻐﻴﺮ اﺳﻤﻪ ‪ quantity‬وأردﻧﺎ إﻧﻘﺎص ﻗﻴﻤﺘﻪ‬
‫;‪return‬‬
‫وﺑﺎﻟﺘﺎﻟﻲ ﺗﺒﻘﻰ ﻗﻴﻤﺔ اﻟﻤﺘﻐﻴﺮ‬ ‫ﺑﻤﻘﺪار واﺣﺪ ﻓﺴﻨﺴﺘﺨﺪم اﻟﺴﻄﺮ ;‪ quantity--‬ﺑﻌﺪ ذﻟﻚ‬
‫}‬ ‫أﻛﺒﺮ ﻣﻦ ﺻﻔﺮ‬
‫;‪quantity--‬‬ ‫ﻟﻜﻲ ﻧﺘﺠﻨﺐ اﻟﺤﺼﻮل ﻋﻠﻰ ﻗﻴﻤﺔ ﺳﺎﻟﺒﺔ ﻧﺴﺘﺨﺪم ﻫﺬه‬

‫‪22‬‬
‫أﺳﻠﻮب اﻟﻤﻘﺼﺪ أو اﻟﻮﺟﻬﺔ ‪INTENT‬‬
‫اﻟـ ‪ Intent‬ﻫﻮ أﺣﺪ اﻻﻣﻮر اﻷﺳﺎﺳﻴﺔ ﻷي ﺗﻄﺒﻴﻖ أﻧﺪروﻳﺪ ‪ ،‬وﻻ‬
‫ﻳﻜــﺎد ﻳﺨﻠﻮ أي ﺗﻄﺒﻴﻖ اﻧـﺪروﻳﺪ ﻣــﻦ اﺳﺘﺨــﺪاﻣﻪ‬
‫وﻳﺴﺘﺨﺪم ﻻرﺳﺎل اﻟﺒﻴﺎﻧﺎت وﻟﻼﻧﺘﻘﺎل ﺑﻴﻦ ﻣﻜﻮﻧﺎت اﻟﺘﻄﺒﻴﻖ‬

‫ﻳﺴﺘﺨﺪم ﻓﻲ اﻻﻧﺘﻘﺎل ﺑﻴﻦ اﻷﻧﺸﻄﺔ ‪Activities‬‬ ‫‪1‬‬


‫ﻳﺤﺪد اﻟﻨﺸﺎط ‪ Activity‬اﻟﺮﺋﻴﺴﻲ اﻟﺬي ﺳﻴﻔﺘﺢ ﻋﻦ ﺗﺸﻐﻴﻞ‬ ‫‪2‬‬
‫ﺗﻤﺮﻳﺮ اﻟﺒﻴﺎﻧﺎت ﺑﻴﻦ اﻷﻧﺸﻄﺔ واﻟﺘﻄﺒﻴﻘﺎت اﻷﺧﺮى‬ ‫‪3‬‬

‫‪EXPLICIT INTENT‬‬ ‫أﻧﻮاع اﻟـــ‪INTENT‬‬ ‫‪IMPLICIT INTENT‬‬


‫ﻣﺤﺪد أو ﺻﺮﻳﺢ‬ ‫ﺿﻤﻨﻲ‬

‫وﻓﻲ ﻫﺬا اﻟﻨﻮع ﻳﺘﻢ ﻣﻌﺮﻓﺔ اﻟﻤﻜﻮن اﻟﺬي ﺳﻴﻘﻮم‬ ‫وﻓﻲ ﻫﺬا اﻟﻨﻮع ﻻ ﻳﺘﻢ ﺗﺤﺪﻳﺪ اﻟﻤﻜﻮن اﻟﺬي ﺳﻴﺴﺘﻘﺒﻞ‬
‫ﺑﺎﺳﺘﻘﺒﺎل ﻫﺬا اﻟـ ‪ Intent‬ﻛﻤﺜﺎل‪ :‬ﻋﻨﺪﻣﺎ ﻳﺤﺘﻮي اﻟﺘﻄﺒﻴﻖ‬ ‫ﻫﺬا اﻟـ ‪ Intent‬ﻛﻤﺜﺎل ﻋﻨﺪﻣﺎ ﻧﺮﻳﺪ أن ﻧﺮﺳﻞ إﻳﻤﻴﻞ‬
‫ﻋﻠﻰ ﺷﺎﺷﺘﻴﻦ وﻧﺮﻳﺪ اﻻﻧﺘﻘﺎل ﻣﻦ اﻟﺸﺎﺷﺔ اﻻوﻟﻰ إﻟﻰ‬ ‫ﺑﺎﺳﺘﺨﺪام ‪ Intent‬ﻓﺈﻧﻨﺎ ﺳﻨﻘﻮم ﺑﺈﺿﺎﻓﺔ ﺑﻴﺎﻧﺎت إﺿﺎﻓﻴﺔ‬
‫اﻟﺸﺎﺷﺔ اﻟﺜﺎﻧﻴﺔ ﻓﺈﻧﻨﺎ ﻧﻘﻮم ﺑﺈﻋﻄﺎء اﺳﻢ اﻟﺸﺎﺷﺔ‬ ‫وﻳﻘﻮم ﻧﻈﺎم اﻟﺘﺸﻐﻴﻞ ﺑﺘﺤﺪﻳﺪ اﻟﻤﻜﻮﻧﺎت اﻟﺘﻲ‬
‫اﻟﺜﺎﻧﻴﺔ ﻟﻠـ ‪ Intent‬ﻟﻴﻘﻮم ﺑﺎﻻﻧﺘﻘﺎل اﻟﻴﻬﺎ‬ ‫ﺑﺈﻣﻜﺎﻧﻬﺎ اﺳﺘﻘﺒﺎل ﻫﺬا اﻟـ ‪ Intent‬وإرﺳﺎل إﻳﻤﻴﻞ‬
‫ﻛﻤﺎ ذﻛﺮﻧﺎ أن ﻓﻲ ‪ Intent‬ﻻ ﻳﺘﻢ ﺗﺤﺪﻳﺪ أﺳﻢ اﻟﻤﻜﻮن‬
‫اﻟﺬي ﻧﺮﻳﺪ اﻟﻮﺻﻮل اﻟﻴﻪ‬
‫ﺳﺆال ﻳﻀﻊ ﻧﻔﺴﻪ ‪ ..‬ﻛﻴﻒ ﻳﺘﻢ اﻟﻮﺻﻮل اﻟﻴﻪ أذن؟؟‬
‫ﻳﺘﻢ اﻟﻮﺻﻮل اﻟﻴﻪ ﻣﻦ ﺧﻼل ﺗﺤﺪﻳﺪ واﺣﺪ ﻋﻠﻰ اﻻﻗﻞ ﻣﻦ‬
‫أرﺑﻌﺔ ﻣﻜﻮﻧﺎت ﻟـ‪ Intent‬وﻣﻦ ﺗﻠﻚ اﻟﻤﻜﻮﻧﺎت ﻳﺘﻢ ﺗﺤﺪﻳﺪ‬
‫اﻟﻮﻇﻴﻔﺔ اﻟﺘﻲ ﺳﻴﻘﻮم ﺑﻬﺎ اﻟـ ‪Intent‬‬
‫وﻫـــﻮ اﻟﻌﻤـــﻞ اﻟﻤﻄﻠــﻮب ﻣــﻦ ﻫــﺬا‬
‫اﻟـ ‪ Intent‬ﻛـﻤﺜﺎل ‪:‬ﻋﻤﻞ اﺗﺼﺎل‪,‬إرﺳﺎل اﻳﻤﻴﻞ‪،‬‬ ‫‪ACTION‬‬
‫ﻋﺮض ﺻﻔﺤﺔ وﻳﺐ إﻟﻰ آﺧﺮه‬
‫‪Explicit Intent‬‬ ‫ﻣﺜﺎل‪ :‬اﻹﻧﺘﻘﺎل إﻟﻰ اﻟﻨﺸﺎط اﻟﺜﺎﻧﻲ ﻋﺒﺮ اﺳﺘﺨﺪام‬
‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬
‫ﻧﻮع اﻟﺒﻴﺎﻧﺎت اﻟﻤﻄﻠﻮب اﻟﺘﻌﺎﻣﻞ ﻣﻌﻬﺎ‬
‫;)‪Intent i = new Intent(getApplicationContext(), ActivityTwo.class‬‬ ‫ﻛﻤﺜﺎل ﻋﻨﺪﻣﺎ ﻧﺮﻳﺪ ﻓﺘﺢ ﺻﻔﺤﺔ وﻳﺐ‬ ‫‪DATA‬‬
‫;)‪startActivity(i‬‬ ‫‪4‬‬ ‫ﻓﻨﺤﺪد ﻧﻮع اﻟﺒﻴﺎﻧﺎت ﻛـ ‪URL‬ﻛﻌﻨﻮان ﺻﻔﺤﺔ‬
‫ﺗﺤﺪﻳﺪ ﻧﻮع ﺑﻴﺎﻧﺎت اﻟﻜﺎﺋﻦ‬ ‫‪1‬‬ ‫اﻟﻮﻳﺐ اﻟﺘﻲ ﻧﺮﻳﺪ ﻓﺘﺤﻬﺎ‬
‫وﻫﻲ ﺑﻴﺎﻧﺎت إﺿﺎﻓﻴﺔ ﻳﺘﻢ إﺳﻨﺎدﻫﺎ ﻟﻬـﺬا‬
‫اﻟﻤﻌﺎﻣﻞ اﻷول ﻓﻲ ‪ Constructor‬اﻟـ ‪ intent‬وﻫﻮ ﻣﻦ‬ ‫‪2‬‬ ‫اﻟـ ‪ Intent‬ﻛـ )‪ (Key/Value‬ﻣﺜﻼ ﻋﻨﺪﻣﺎ ﻧﻘﻮم‬
‫ﻧﻮع ‪ context‬وﻫﻨﺎ ﺗﻢ اﺳﺘﺨﺪام ‪ context‬اﻟﺘﻄﺒﻴﻖ‬
‫‪ EXTRAS‬ﺑﺈﻧﺸﺎء ‪ Intent‬ﻳﻔﺘﺢ ﺻﻔﺤﺔ وﻳﺐ ﻓﻨﺤﺪد‬
‫اﻟﻤﻌﺎﻣﻞ اﻟﺜﺎﻧﻲ ﻓﻲ‪ Constructor‬اﻟـ‪ intent‬وﻫﻮ ﻣﻦ‬ ‫‪3‬‬ ‫ﻋﻨﻮان اﻟﺼﻔﺤﺔ اﻟﺘﻲ ﻧﺮﻳﺪ ﻓﺘﺤﻬﺎ‪ ،‬ﻳﺘﻢ‬
‫ﻧﻮع ‪ java class‬وﻫﻨﺎ ﺗﻢ اﺳﺘﺨﺪام ﺻﻨﻒ اﻟﻨﺸﺎط‬ ‫إﺳﻨﺎد ﻋﻨﻮان ﺗﻠﻚ اﻟﺼﻔﺤﺔ ﻫﻨﺎ‬
‫اﻟﺜﺎﻧﻲ ﻟﻺﻧﺘﻘﺎل إﻟﻴﻪ‬ ‫وﻫﻲ اﻟﻔﺌﺎت واﻟﻐﺮض ﻣﻨﻬﺎ ﺗﺤﺪﻳﺪ‬
‫ﻫـــﺬه اﻟﻄﺮﻳﻘـﺔ ‪ method‬ﺗﺴﺘﺨـﺪم ﻟﺒــﺪأ ﻋﻤﻠﻴـــﺔ‬ ‫‪4‬‬ ‫‪ CATEGORY‬وﺗﻨﻈﻴﻢ ﻣﻜﻮﻧﺎت‪ ،‬ﻛﻤﺜــﺎل‪ :‬ﺗﺤﺪﻳــﺪ اﻟـ‪،‬‬
‫اﻟـ ‪ intent‬واﻹﻧﺘﻘﺎل إﻟﻰ اﻟﻨﺸﺎط اﻟﺜﺎﻧﻲ ﻓﻲ ﻫﺬه‬ ‫ﺗﺼﻨﻴﻒ اﻟﻤﻜﻮﻧﺎت ﻋﻠﻰ ﺣﺴﺐ اﻟﻮﻇﻴﻔﺔ‬
‫اﻟﺤﺎﻟﺔ‬ ‫وﻏﻴﺮﻫﺎ‬

‫‪23‬‬
IMPLICIT INTENT ‫أﻣﺜﻠﺔ ﻋﻠﻰ‬

public void sendEmail(View v) { ‫إرﺳﺎل ﺑﺮﻳﺪ إﻟﻜﺘﺮوﻧﻲ‬ 1


‫ ﻹرﺳﺎل ﺑﻴﺎﻧﺎت‬ACTION_SEND ‫ﺟﺪﻳﺪ ﻣﻦ ﻧﻮع‬INTENT ‫ﻧﻌﺮف‬ Intent i = new Intent(Intent.ACTION_SEND);
DATA ‫إﺿﺎﻓﺔ ﺑﻴﺎﻧﺎت اﻟـ‬ i.setData(Uri.parse("mailto:"));
‫ﺗﺠﻬﻴﺰ ﻣﺼﻔﻮﻓﺔ ﻣﻦ إﻳﻤﻴﻼت اﻟﻤﺴﺘﻠﻤﻴﻦ‬ String [] to={"xxx@gmail.com","xxx@gmail.com"};
EXTRA ‫إﺿﺎﻓﺔ ﻣﺼﻔﻮﻓﺔ اﻹﻳﻤﻴﻼت إﻟﻰ‬ i.putExtra(Intent.EXTRA_EMAIL,to);
EXTRA ‫إﺿﺎﻓﺔ ﻋﻨﻮان رﺳﺎﻟﺔ اﻟﺒﺮﻳﺪ اﻹﻟﻜﺘﺮوﻧﻲ إﻟﻰ‬ i.putExtra(Intent.EXTRA_SUBJECT,"This is subject");
EXTRA ‫إﺿﺎﻓﺔ ﻧﺺ رﺳﺎﻟﺔ اﻟﺒﺮﻳﺪ اﻹﻟﻜﺘــﺮوﻧﻲ إﻟﻰ‬ i.putExtra(Intent.EXTRA_TEXT,"This is body");
‫ﺗﺤﺪﻳﺪ ﻧﻮع اﻟﺒﻴﺎﻧﺎت ﻓﻲ اﻹﻳﻤﻴﻞ إﻟﻰ ﻧﺼﻮص‬ i.setType("plain/text");
‫ وإرﺳﺎل اﻹﻳﻤﻴﻞ‬INTENT ‫ﺑﺪأ ﺗﻨﻔﻴﺬ اﻟـ‬ startActivity(i);
}

‫ارﺳﺎل رﺳﺎﻟﺔ ﻧﺼﻴﺔ‬ 2


public void sendSMS(View v){
‫ ﻹرﺳﺎل ﺑﻴﺎﻧﺎت‬ACTION_SENDTO ‫ ﻣﻦ ﻧﻮع‬INTENT ‫ﻧﻌﺮف‬ Intent it = new Intent(Intent.ACTION_SENDTO);
‫ وﻫﻲ ﻫﻨﺎ رﻗﻢ ﻫﺎﺗﻒ اﻟﻤﺴﺘﻘﺒﻞ‬DATA ‫إﺿﺎﻓﺔ ﺑﻴﺎﻧﺎت اﻟـ‬ it.setData(Uri.parse("smsto:12346556"));
EXTRA ‫إﺿﺎﻓﺔ ﻧﺺ اﻟﺮﺳﺎﻟﺔ إﻟﻰ‬ it.putExtra("sms_body", "The SMS text to be sent");
‫ وإرﺳﺎل رﺳﺎﻟﺔ ﻧﺼﻴﺔ‬INTENT ‫ﺑﺪأ ﺗﻨﻔﻴﺬ اﻟـ‬ startActivity(it);
}
‫ﻓﺘﺢ ﺧﺮاﺋﻂ ﺟﻮﺟﻞ‬ 3
public void openGoogleMap(View v){
‫ ﻟﻌﺮض ﺑﻴﺎﻧﺎت‬ACTION_VIEW ‫ ﺟﺪﻳﺪ ﻣﻦ ﻧﻮع‬INTENT ‫ ﻧﻌﺮف‬Intent i = new Intent(android.content.Intent.ACTION_VIEW);
‫ وﻫﻲ ﻫﻨﺎ إﺣﺪاﺛﻴﺎت اﻟﻤﻮﻗﻊ‬DATA ‫إﺿﺎﻓﺔ ﺑﻴﺎﻧﺎت اﻟـ‬ i.setData(Uri.parse("geo:18.09,77,776"));
‫ وإرﺳﺎل اﻻﺣﺪاﺛﻴﺎت‬INTENT ‫ ﺑﺪأ ﺗﻨﻔﻴﺬ اﻟـ‬startActivity(i);
}
‫ﻓﺘﺢ ﺑﺮﻧﺎﻣﺞ اﻟﻤﺘﺼﻞ‬ 4
public void makeCall(View v ){
‫ ﻟﺒﺪء اﺗﺼﺎل‬ACTION_DIAL ‫ ﺟﺪﻳﺪ ﻣﻦ ﻧﻮع‬INTENT ‫ﻧﻌﺮف‬ Intent i = new Intent(Intent.ACTION_DIAL);
‫ وﻫﻲ ﻫﻨﺎ رﻗﻢ ﻫﺎﺗﻒ اﻟﻤﺘﺼﻞ ﺑﻪ‬DATA ‫إﺿﺎﻓﺔ ﺑﻴﺎﻧﺎت اﻟـ‬ i.setData(Uri.parse("tel:223432144"));
‫ وإرﺳﺎل اﻻﺣﺪاﺛﻴﺎت‬INTENT ‫ﺑﺪأ ﺗﻨﻔﻴﺬ اﻟـ‬ startActivity(i);
}

4 3 2 1

24
‫اﻟﺘﻨﺴﻴﻘﺎت ‪STYLES‬‬
‫ﺗﺴﺘﺨﺪم ﻣﻮارد اﻟﺘﻨﺴﻴﻘﺎت ‪ Styles‬ﻟﺤﻔﻆ ﺗﻨﺴﻴﻖ اﻟﻌﻨﺎﺻﺮ ﻓﻲ ﻣﻜﺎن واﺣﺪ ﻣﻤﺎ ﻳﺴﺎﻋﺪ ﻓﻲ ﺣﺎل أردﻧﺎ ﺗﻌﺪﻳﻞ اﻟﺘﻨﺴﻴﻖ‬
‫اﻟﺮﺟﻮع إﻟﻰ ﻣﻜﺎن واﺣﺪ وﺗﻐﻴﻴﺮه ﻓﻴﺘﻐﻴﺮ اﻟﺘﻨﺴﻴﻖ ﻓﻲ ﻛﻞ اﻟﺘﻄﺒﻴﻖ وﻫﻲ ﺗﺸﻤﻞ اﻷﻃﻮال‪ ،‬اﻟﻬﻮاﻣﺶ‪ ،‬اﻟﺤﺸﻮ‪ ،‬اﻷﻟﻮان‪،‬‬
‫أﺣﺠﺎم وأﻟﻮان اﻟﺨﻄﻮط وﻏﻴﺮﻫﺎ‬
‫>?"‪<?xml version="1.0" encoding="utf-8‬‬
‫>‪<resources‬‬ ‫ﻣﺜﺎل‪ :‬ﻧﻌﺮف ﻫﻨﺎ ﻟﻮن اﻟﺨﻂ ﻓﻲ اﻟﻤﻠﻒ ‪styles.xml‬‬
‫>"‪<style name="GreenText" parent="TextAppearance.AppCompat‬‬ ‫اﻟﻤﻮﺟﻮد ﻓﻲ اﻟﻤﻮارد‬
‫>‪<item name="android:textColor">#00FF00</item‬‬
‫ﺛﻢ ﻧﺤﺬف ﻣﻴﺰة ﻟﻮن اﻟﺨﻂ ﻓﻲ ﻋﻨﺼﺮ اﻟﻌﺮض‬
‫>‪</style‬‬
‫ﻧﻀﻊ اﻟﻤﻴﺰة ‪ style‬ﻣﻜﺎﻧﻬﺎ‪ ،‬ﻓﺒﻬﺬه اﻟﻄﺮﻳﻘﺔ‬
‫>‪</resources‬‬
‫أﺻﺒﺤﺎ ﻫﻨﺎك ارﺗﺒﺎط ﺑﻴﻦ ﻋﻨﺼﺮ وﻣﻠﻒ اﻟﺘﻨﺴﻴﻖ‬
‫‪<TextView‬‬ ‫ﺑﺎﻟﻨﺴﺒﺔ ﻟﻠﻮن اﻟﺨﻂ‬
‫"‪style="@style/GreenText‬‬
‫‪Theme‬‬
‫>‪... /‬‬

‫اﻟﺘﻨﺴﻴﻘﺎت اﻟﺴﻤﺔ ‪STYLES AS A THEME‬‬


‫ﻧﺴﺘﻄﻴﻊ ﻣﻦ ﺧﻼل اﻟﺴﻤﺔ اﻟﺘﺤﻜﻢ ﻓﻲ ﺗﻨﺴﻴﻖ ﺟﻤﻴﻊ ﻋﻨﺎﺻﺮ اﻟﻌﺮض ﻓﻲ ﻧﺸﺎط ﻣﺎ أو ﻓﻲ اﻟﺘﻄﺒﻴﻖ ﺑﺸﻜﻞ ﻋﺎم‪ ،‬وﻫﻨﺎك‬
‫ﺳﻤﺎت ﻣﺮﻓﻘﺔ ﻣﻊ ﺣﺰﻣﺔ اﻷﻧﺪرﻳﻮد ﻳﻤﻜﻦ ﻣﻦ ﺧﻼﻟﻬﺎ ﺗﺤﺪﻳﺪ ﺗﻨﺴﻴﻘﺎت ﻣﻌﺮﻓﺔ ﻣﺴﺒﻘﺎ‪ ،‬أو ﻳﻤﻜﻨﻨﺎ ﻋﻤﻞ ﺗﻨﺴﻴﻖ‬
‫ﺟﺪﻳﺪﻛﻤﺎ ﻓﻌﻠﻨﺎ ﻟﻠﻌﻨﺎﺻﺮ ﻓﻲ ﻗﺴﻢ اﻟﺴﺘﺎﻳﻞ‬
‫ﻧﺴﺘﺨﺪم ﻫﺬه اﻹﺿﺎﻓﺔ وﻫﻲ اﺧﺘﺼﺎر ﻟـ ‪ App Compatibility‬ﻟﺠﻌﻞ اﻟﺘﻨﺴﻴﻖ ﻣﺘﻮاﻓﻖ ﻣﻊ اﻷﻧﻈﻤﺔ اﻷﻗﺪم ﻣﻦ اﻷﻧﺪرﻳﻮد‬

‫>"‪<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar‬‬


‫>‪<item name="colorPrimaryDark">@color/colorPrimaryDark</item‬‬
‫>‪<item name="colorPrimary">@color/colorPrimary</item‬‬
‫>‪<item name="colorAccent">@color/colorAccent</item‬‬
‫>‪</style‬‬ ‫اﻟﺴﻤﺎت اﻟﺮﺋﻴﺴﻴﺔ‬

‫‪Theme.Material.Dark‬‬ ‫‪Theme.Material.Light‬‬ ‫‪Theme.Material.Light.DarkActionBar‬‬

‫‪25‬‬
‫ﻣﻠﻒ اﻟﻮاﺟﻬﺔ ‪MAINFEST.XML‬‬
‫وﻫﻮ أول ﻣﻠﻒ ﻳﺘﻢ ﺗﺸﻐﻴﻠﻪ ﻋﻨﺪ ﻓﺘﺢ اﻟﺘﻄﺒﻴﻖ وﻳﻌﺘﺒﺮ ﺟﺪول ﻣﺤﺘﻮﻳﺎت ﻟﻌﻨﺎﺻﺮ اﻟﺘﻄﺒﻴﻖ ﺑﺤﻴﺚ ﻳﻌﺮف ﻓﻴﻪ اﻟﺸﺎﺷﺎت‬
‫اﻟﻤﻮﺟﻮدة واﻷذوﻧﺎت ﻹﺳﺘﺨﺪام ﻣﻮارد اﻟﺠﻬﺎز اﻷﻧﺪرﻳﻮد واﻟﺘﻲ ﺳﻴﺤﺘﺎﺟﻬﺎ اﻟﺘﻄﺒﻴﻖ ﻣﺜﻼ اﻟﺴﻤﺎح ﻟﻠﺘﻄﺒﻴﻖ ﺑﻌﻤﻞ اﺗﺼﺎل‬
‫أو اﻟﺪﺧﻮل إﻟﻰ اﻹﻧﺘﺮﻧﺖ‬
‫ﻓﻲ اﻟﺼﻔﺤﺔ اﻟﺴﺎﺑﻘﺔ ﺗﻢ ﺗﺤﺪﻳﺪ اﻟﺴﻤﺔ ‪ Theme‬ﻟﺘﻨﺴﻴﻖ ﻋﻨﺎﺻﺮ اﻟﺘﻄﺒﻴﻖ وﻳﺘﻢ ﻫﺬا داﺧﻞ اﻟﻤﻠﻒ اﻟـ ‪Mainfest.xml‬‬
‫ﺷﺮح أﻫﻢ اﻷوﺳﻤﺔ ﻓﻲ ﻣﻠﻒ ‪Mainfest.xml‬‬
‫>?"‪ <?xml version="1.0" encoding="utf-8‬رﻗﻢ إﺻﺪار اﻟﻜﻮد اﻟﻤﺼﺪر وﻫﺬه اﻟﺨﺎﺻﻴﺔ ﺧﺎﺻﺔ ﻓﻘﻂ‬
‫"‪ <manifest xmlns:android="http://schemas.android.com/apk/res/android‬ﺑﺎﻟﻤﺒﺮﻣﺞ أو ﺑﻜﻮد اﻟﺒﺮﻧﺎﻣﺞ‪ ،‬ﻳﻔﻀﻞ ﻋﻨﺪ ﺗﻌﺪﻳﻞ أى ﺳﻄﺮ‬
‫"‪ android:versionCode="1‬ﻓﻰ اﻟﻜﻮد ان ﻳﺘﻢ ﺗﺤﺪﻳﺚ ﻫﺬه اﻟﺨﺎﺻﻴﺔ ﺣﺘﻰ ﻳﻤﻴﺰ‬
‫"‪ android:versionName="1.0‬اﻟﻤﺒﺮﻣﺞ ﺑﻴﻦ اﻻﺻﺪارات اﻟﻤﺨﺘﻠﻔﺔ ﻣﻦ اﻟﻜﻮد‬ ‫اﺳﻢ ﺣﺰﻣﺔ اﻟﺘﻄﺒﻴﻖ‬
‫رﻗﻢ اﻹﺻﺪار اﻟﺨﺎص ﺑﺎﻟﻤﺴﺘﺨﺪم أو اﻟﺬي ﺳﻴﻈﻬﺮ ﻓﻰ‬ ‫>"‪package="com.example.myapp‬‬
‫ﻣﺘﺠﺮ ﺟﻮﺟﻞ ﺑﻼى وﻟﻴﺲ ﺿﺮورى ﺗﻐﻴﻴﺮه ﻛﻞ ﻣﺮة وﻟﻜﻦ‬
‫ﻫﺬا ﺣﺴﺐ إذا ﻛﺎن اﻟﺘﻐﻴﻴﺮ ﺟﻮﻫﺮي أو ﺛﺎﻧﻮي‬
‫>‪ <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="26" /‬رﻗﻢ ﻧﺴﺦ ﺣﺰم اﻷﻧﺪرﻳﻮد اﻟﺘﻲ ﺳﻴﺪﻋﻤﻬﺎ اﻟﺘﻄﺒﻴﻖ‪،‬‬
‫أﻗﻞ ﻧﺴﺨﺔ واﻟﻨﺴﺨﺔ اﻟﺤﺎﻟﻴﺔ ﻟﻠﺘﻄﺒﻴﻖ‬
‫>‪ <uses-permission android:name="android.permission.INTERNET" /‬إﻋﻄﺎء اﻷذوﻧﺎت ﻟﻠﺘﻄﺒﻴﻖ ﻹﺳﺘﺨﺪام ﻣﻮادر اﻟﺠﻬﺎز‪،‬‬
‫‪ <application‬ﻣﺜﻞ اﻟﺴﻤﺎح ﻟﻠﺘﻄﺒﻴﻖ ﺑﺎﺳﺘﺨﺪام اﻹﻧﺘﺮﻧﺖ‬
‫اﻟﺴﻤﺎح ﺑﻌﻤﻞ ﻧﺴﺨﺔ اﺣﺘﻴﺎﻃﻴﺔ ﻣﻦ اﻟﺘﻄﺒﻴﻖ‬ ‫"‪android:allowBackup="true‬‬
‫ﻋﻨﺪ اﺧﺘﻴﺎر ‪ Backup‬ﻣﻦ ﺧﻴﺎرات ﻟﻠﺠﻬﺎز‬
‫ﺗﺤﺪﻳﺪ أﻳﻘﻮﻧﺔ اﻟﺘﻄﺒﻴﻖ ﻣﻦ ﻣﻠﻒ اﻟﻤﻮارد ‪mipmap‬‬ ‫"‪android:icon="@mipmap/ic_launcher‬‬
‫ﺗﺤﺪﻳﺪ أﻳﻘﻮﻧﺔ اﻟﺘﻄﺒﻴﻖ ﻣﻦ اﻟﻨﻮع اﻟﺪاﺋﺮي‬ ‫"‪android:roundIcon="@mipmap/ic_launcher_round‬‬
‫اﺳﻢ اﻟﺘﻄﺒﻴﻖ اﻟﺬي ﻳﻈﻬﺮ ﻟﻠﻤﺴﺘﺨﺪم‬ ‫"‪android:label="@string/app_name‬‬
‫ﺗﻔﻌﻴﻞ ﻣﺤﺎذاة اﻟﻴﻤﻴﻦ إﻟﻰ اﻟﻴﺴﺎر ﻓﻲ اﻟﺘﻄﺒﻴﻖ‬ ‫"‪android:supportsRtl="true‬‬
‫اﺳﻢ اﻟﺴﺘﺎﻳﻞ اﻟﺬي ﺳﻴﺴﺘﺨﺪم ﻟﺘﻨﺴﻴﻖ اﻟﺘﻄﺒﻴﻖ‬ ‫>"‪android:theme="@style/AppTheme‬‬
‫‪ ------------------------------------------------------‬ﻗﺴﻢ ﻣﻌﻠﻮﻣﺎت اﻟﺸﺎﺷﺎت ‪---------- Activities‬‬
‫ﺗﺤﺪﻳﺪ ﻣﺴﺎر واﺳﻢ اﻟﺸﺎﺷﺔ‬ ‫>"‪<activity android:name=".MainActivity‬‬
‫>‪<intent-filter‬‬
‫اﺳﺘﺨﺪام اﻟـ ‪ Intent‬ﻟﻠﺘﺼﺮﻳﺢ أن ﻫﺬه ﻫﻲ اﻟﺸﺎﺷﺔ‬ ‫>‪<action android:name="android.intent.action.MAIN" /‬‬
‫اﻟﺮﺋﻴﺴﻴﺔ وﻳﻼﺣﻆ اﺳﺘﺨﺪام ‪ action‬و ‪category‬‬ ‫>‪<category android:name="android.intent.category.LAUNCHER" /‬‬
‫>‪</intent-filter‬‬
‫>‪</activity‬‬
‫>‪</application‬‬
‫>‪</manifest‬‬

‫ﻟﻠﺤﺼﻮل ﻋﻠﻰ اﻟﻘﺎﺋﻤﺔ اﻟﻜﺎﻣﻠﺔ ﻟﻸوﺳﻤﺔ ﻳﺮﺟﻰ اﻟﺮﺟﻮع ﻟﻠﻤﻮﻗﻊ اﻟﺘﺎﻟﻲ‬


‫>‪<application‬‬ ‫‪https://developer.android.com/guide/topics/manifest/application-element.html‬‬
‫‪....‬‬
‫ﻋﻨﺪ ﻋﻤﻞ أي ﺷﺎﺷﺔ ﺟﺪﻳﺪة ﻳﺠﺐ ﺗﻌﺮﻳﻔﻬﺎ ﻓﻲ‬
‫> "‪<activity android:name=".YourActivityName2‬‬
‫ﻣﻠﻒ ‪ Mainfest.xml‬ﻟﻴﺴﺘﻄﻴﻊ اﻟﺘﻄﺒﻴﻖ اﻟﺘﻌﺮف‬
‫>‪</application‬‬
‫ﻋﻠﻴﻬﺎ‬
‫>‪</manifest‬‬

‫‪26‬‬
‫اﻟﻤﻮارد اﻟﺒﺪﻳﻠﺔ ‪ALTERNATIVE RESOURCES‬‬
‫ﻟﺠﻌﻞ اﻟﺘﻄﺒﻴﻖ ﻳﻌﻤﻞ ﺑﺸﻜﻞ ﺟﻴﺪ أﻧﻮع اﻷﺟﻬﺰة‬
‫اﻟﻤﺴﺘﺨﺪﻣﺔ ﻣﺜﻞ ﻫﺎﺗﻒ‪ ،‬اﻟﺠﻬﺎز اﻟﻠﻮﺣﺔ‪ ،‬اﻟﺤﺎﺳﺐ اﻵﻟﻲ‬
‫وﻏﻴﺮﻫﺎ‪ ،‬أﺣﺪ اﻟﻨﻘﺎط اﻟﻤﻬﻤﺔ اﻟﺘﻲ ﻳﺠﺐ ﻣﺮاﻋﺎﺗﻬﺎ ﻫﻮ‬
‫ﺗﺮﺟﻤﺔ اﻟﺘﻄﺒﻴﻖ‬
‫ﺗﻜﻤﻦ ﻓﺎﺋﺪة ﻓﺼﻞ اﻟﻤﻮارد ﻋﻦ ﻛﻮدات ﺟﺎﻓﺎ ﺑﺄﻧﻪ ﺳﻴﻜﻮن‬
‫ﻣﻦ اﻟﺴﻬﻞ ﺗﺤﺪﻳﺪ ﻣﻮارد ﺑﺪﻳﻠﺔ ﻟﻠﻐﺎت ﻣﺨﺘﻠﻔﺔ وﻛﺬﻟﻚ‬
‫ﻷﺣﺠﺎم ﺷﺎﺷﺎت وأﻧﻈﻤﺔ أﻧﺪرﻳﻮد ﻣﺨﺘﻠﻔﺔ ﻋﻨﺪ اﻟﺤﺎﺟﺔ‬

‫ﻣﻘﺎﺳﺎت ﻣﺨﺘﻠﻔﺔ‬ ‫اﻟﻤﻮارد اﻷﺳﺎﺳﻴﺔ ‪Default Resources‬‬ ‫‪1‬‬


‫أﺣﺠﺎم ﺷﺎﺷﺎت ﻣﺨﺘﻠﻔﺔ‬
‫ﺧﻴﺎرات اﻟﻠﻐﺔ‬ ‫اﻟﻤـﻮارد اﻟﺒﺪﻳﻠــﺔ ‪Alternative Resources‬‬ ‫‪2‬‬
‫ﻧﺴﺦ أﻧﺪرﻳﻮد ﻣﺨﺘﻠﻔﺔ‬
‫اﻟﻨﺼﻮص اﻟﺘﻲ ﺗﻢ إﺿﺎﻓﺘﻬﺎ ﻓﻲ ﻣﻠﻒ ‪ strings.xml‬ﻳﻤﻜﻦ ﻋﻤﻞ ﻋﺪة ﺗﺮﺟﻤﺎت ﻟﻬﺎ‪ ،‬وﺳﻴﺨﺘﺎر اﻟﻨﻈﺎم اﻟﻠﻐﺔ اﻟﻤﻨﺎﺳﺒﺔ‬
‫‪strings.xml‬‬ ‫ﺣﺴﺐ ﻟﻐﺔ ﺟﻬﺎز اﻟﻤﺴﺘﺨﺪم‪ ,‬وﻫﻨﺎ اﻟﺨﻄﻮات ﻟﻌﻤﻞ ﺗﺮﺟﻤﺔ ﺟﺪﻳﺪة‬

‫ﻳﺘﻢ اﻟﻀﻐﻂ ﻋﻠﻰ ﻣﻮرد اﻟﻨﺼﻮص اﻷﺳﺎﺳﻲ‬ ‫‪1‬‬


‫ﺑﺎﻟﺰر اﻷﻳﻤﻦ واﺧﺘﻴﺎر ‪Open Translation Editor‬‬
‫ﺳﺘﻔﺘﺢ ﺷﺎﺷﺔ اﻟﺘﺮﺟﻤﺎت‬ ‫‪2‬‬
‫وﻳﻈﻬﺮ ﻋﻠﻰ اﻟﻴﺴﺎر ﻗﺎﺋﻤﺔ‬
‫اﻟﻨﺼﻮص اﻟﻤﻮﺟﻮدة وﻗﻴﻤﻬﺎ‬
‫واﻟﺘﺮﺟﻤﺎت اﻟﺘﻲ ﺗﻘﺎﺑﻠﻬﺎ‬
‫ﺑﺎﻟﻠﻐﺎت اﻷﺧﺮى‪ ،‬ﻳﻤﻜﻦ ﻋﺪم‬
‫ﺗﺮﺟﻤﺔ ﻧﺺ ﻣﻌﻴﻦ ﺑﻮﺿﻊ ﻋﻼﻣﺔ‬
‫ﺻﺢ ﻓﻲ ﻋﻤﻮد ‪Untranslatable‬‬

‫ﻹﺿﺎﻓﺔ ﻟﻐﺔ ﺟﺪﻳﺪ ﻳﻤﻜﻦ إﺿﺎﻓﺘﻬﺎ‬ ‫‪3‬‬


‫ﻟﻜﻞ ﻟﻐﺔ ﻳﺘﻢ ﺗﻌﺮﻳﻔﻬﺎ ﺳﻴﺘﻢ ﻋﻤﻞ ﻣﻠﻒ‬ ‫‪4‬‬ ‫ﺑﺎﻟﻀﻐﻂ ﻋﻠﻰ اﻟــﺰر ‪Add locale‬‬
‫ﺟﺪﻳﺪ ‪ strings.xml‬وإﺿﺎﻓﺔ ﺣﺮﻓﻴﻦ ﻳﺪﻻن‬
‫ﻋﻠﻰ اﻟﻠﻐﺔ اﻟﻤﺘﺮﺟﻤﺔ ‪،‬ﻣﺜﻼ اﻟﺘﺮﺟﻤﺔ إﻟﻰ‬
‫اﻟﻠﻐﺔ اﻟﻌﺮﺑﻴﺔ )‪strings.xml (ar‬‬

‫‪http://www.oracle.com/technetwork/java/javase/java8locales-2095355.html‬‬ ‫ﻟﻤﻌﺮﻓﺔ اﻟﻤﺰﻳﺪ ﻳﺮﺟﻰ اﻟﺮﺟﻮع ﻟﻠﻤﻮﻗﻊ اﻟﺘﺎﻟﻲ‬

‫‪27‬‬
‫ﺗﺎﺑــﻊ‬ ‫اﻟﻤﻮارد اﻟﺒﺪﻳﻠﺔ ‪ALTERNATIVE RESOURCES‬‬
‫ﻟﻠﺘﺬﻛﻴﺮ ﺑﺄن ﻣﻠﻒ اﻟﻨﺼﻮص ‪ strings.xml‬ﻳﺴﺘﺨﺪم ﻟﻮﺿﻊ اﻟﻨﺼﻮص ﻓﻴﻪ ﺑﺪل وﺿﻌﻬﺎ ﻓﻲ ﻛﻮدات ﺟﺎﻓﺎت أو ﻓﻲ واﺟﻬﺔ‬
‫اﻟﺘﻄﺒﻴﻖ ‪XML‬‬

‫ﻫﺬه اﻟﻤﻴﺰة ﺗﺤﻤﻞ ﺧﺎﺻﻴﺔ اﻟﻨﺺ وﻗﺪﻛﺘﺒﺖ ﻣﺒﺎﺷﺮ‪ ،‬وﻳﺴﻤﻰ ﻫﺬا اﻟﻨﻮع ‪hardcoded‬‬
‫وﻳﺼﻌﺐ ﺗﻌﺪﻳﻠﻬﺎ ﻓﻲ اﻟﻤﺴﺘﻘﺒﻞ وﺧﺎﺻﺔ إذا ﻛﺜﺮت اﻟﻨﺼﻮص‬
‫ﻫﻨﺎ ﻛﺘﺒﺖ اﻟﻤﻴﺰة ﻧﻔﺴﻬﺎ ﺑﻌﻤﻞ ﻣﺮﺟﻊ ﻟﻬﺎ ﻣﻦ ﻣﻠﻒ ‪ strings.xml‬ﻓﺒﺎﻟﺘﺎﻟﻲ‬
‫ﺳﻴﺴﻬﻞ ﺗﺮﺟﻤﺘﻬﺎ أو ﺗﻌﺪﻳﻠﻬﺎ‬

‫ﺑﻌﺾ اﻷﺣﻴﺎن ﻧﺤﺘﺎج إﻟﻰ ﻋﺪم ﺗﺮﺟﻤﺔ ﻗﺴﻢ ﻣﻌﻴﻦ ﻣﻦ اﻟﻨﺼﻮص أو ﻋﺪة ﻛﻠﻤﺎت ﻓﻠﻌﻤﻞ ﻫﺬا ﻧﺴﺘﺨﺪم ﻫﺬه اﻟﻮﺳﻮم ﻓﻲ‬
‫ﻣﻠﻒ ‪strings.xml‬‬
‫"‪xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2‬‬
‫وﻫﺬا اﻟﺴﻄﺮ ﻳﺤﺪد أﻧﻨﺎ ﺳﻨﺴﺘﺨﺪم ﻣﺴﺎﺣﺔ اﻹﺳﻢ ‪ namespace‬اﻟﺨﺎﺻﺔ ﺑـ ‪xliff‬‬
‫>‪<string name="order_summary_name">Name: <xliff:g id="name" example="Amy">%s</xliff:g></string‬‬
‫وﻫﻨﺎ ﺳﻮف ﻳﻈﻬﺮ اﻟﻨﺺ‪ Name:‬وﺑﻌﺪه اﺳﺘﺨﺪﻣﻨﺎ ﻣﻴﺰة ‪ xliff‬ﻓﻤﺎ ﺳﻨﻜﺘﺒﻪ ﻫﻨﺎ ﻟﻦ ﻳﺘﻢ ﺗﺮﺟﻤﺘﻪ‬

‫ﻳﻤﻜﻦ ﻛﺬﻟﻚ وﺿﻊ اﻟﻮﺳﻢ "‪ translatable="false‬ﻟﻌﺪم ﺗﺮﺟﻤﺔ اﻟﻨﺺ ﺑﺎﻟﻜﺎﻣﻞ‬


‫>‪<string name="quantity" translatable="false">Quantity</string‬‬

‫اﻟﺪرس اﻟﺤﺎدي ﻋﺸﺮ‪ :‬اﻷﻫﺪاف واﻷﻧﺸﻄﺔ‬ ‫‪11‬‬


‫ﻋﻤﻞ ﺗﻄﺒﻴﻖ ﻣﺘﻜﺎﻣﻞ ‪CREATE COMPLETE APP‬‬
‫ﺳﺘﻘﻮم ﺑﺘﺼﻤﻴﻢ ﺗﻄﺒﻴﻖ ﻓﻲ اﻟﻤﺴﺘﻘﺒﻞ ﻓﻴﺠﺐ أن ﺗﺤﺪدﻛﻴﻒ ﺳﺘﺒﺪأ؟ وﻣﺎﻟﺬي ﺳﺘﺤﺘﺎﺟﻪ؟ وﻛﻢ ﻣﻦ اﻟﻮﻗﺖ ﺳﺘﺤﺘﺎج؟‬

‫ﻓﻲ اﻟﻤﺜﺎل ﻫﻨﺎك ﻋﺪة أﺻﻨﺎف ﻣﻦ اﻟﻜﻠﻤﺎت ﻳﺠﺐ وﺿﻌﻬﺎ ﻓﻲ ﻗﺎﺋﻤﺔ ﺑﺎﻟﻠﻐﺔ اﻹﻧﺠﻠﻴﺰﻳﺔ وﺑﺎﻟﻠﻐﺔ ‪Miwok‬‬

‫ﻋﺮض ﺻﻮر ﻓﻲ اﻟﻘﺎﺋﻤﺔ‬ ‫‪4‬‬ ‫ﻋﺮض زر ﺗﺸﻐﻴﻞ اﻟﺼﻮت‬ ‫‪3‬‬ ‫ﻋﺮض ﻗﺎﺋﻤﺔ ﻛﻠﻤﺎت‬ ‫‪2‬‬ ‫ﻋﺮض ﻋﺪة ﺷﺎﺷﺎت‬ ‫‪1‬‬

‫‪3‬‬

‫ﻗﺎﺋﻤﺔ اﻟﺠُ ﻤﻞ‬ ‫ﻗﺎﺋﻤﺔ اﻷﻟﻮان‬ ‫ﻗﺎﺋﻤﺔ اﻟﻌﺎﺋﻠﺔ‬ ‫ﻗﺎﺋﻤﺔ اﻷرﻗﺎم‬ ‫اﻟﺸﺎﺷﺔ اﻟﺮﺋﻴﺴﻴﺔ‬

‫‪28‬‬
CLASS TYPES ‫أﻧﻮاع اﻷﺻﻨﺎف‬
‫ ﻓﺈﻧﻬﺎ ﺗﻌﻄﻲ اﻟﻤﺠﺎل ﻟﻠﻤﺒﺮﻣﺞ ﺑﻜﺘﺎﺑﺔ ﻛﻮدات‬object oriented language ‫ﻟﻜﻮن اﻟﺠﺎﻓﺎ ﻟﻐﺔ ﺑﺮﻣﺠﺔ ﻣﻮﺟﻬﺔ ﻟﻠﻜﺎﺋﻨﺎت‬
Interface, Abstract and Concrete ‫وﺗﻨﻘﺴﻢ اﻷﺻﻨﺎف إﻟﻰ‬reusability ‫أﺻﻨﺎف ﺗﺼﻠﺢ ﻹﻋﺎدة اﻹﺳﺘﺨﺪام‬

(Not implemented) Interface Class ‫ﺻﻨﻒ اﻟﻮاﺟﻬﺔ‬ 1


‫ ﻟﻜﻦ ﻓﻘﻂ ﻳﻮﺟﺪ ﺗﻌﺮﻳﻒ ﻟﻠﻄﺮق اﻟﺨﺎﻟﻴﺔ وﺗﺴﻤﻰ‬methods ‫ﺻﻨﻒ اﻟﻮاﺟﻬﺔ ﻻ ﻳﺤﺘﻮي أي ﻛﻮدات داﺧﻞ اﻟﻄﺮق‬
‫ أي أن ﻗﻴﻤﺘﻬﺎ ﻻ ﺗﺘﻐﻴﺮ‬static ‫ وأﻳﻀﺎ ﻳﻮﺟﺪ ﻣﺘﻐﻴﺮات ﻣﻦ ﻧﻮع‬Abstract methods ‫ﺑﺎﺳﻢ‬
public interface Brain{
‫ﻛﻞ اﻟﻄﺮق ﻓﻲ ﺻﻨﻒ اﻟﻮاﺟﻬﺔ ﻣﻤﻜﻦ ﺗﺤﻤﻞ أﺣﺪ ﻛﺬه‬
public static final int number = 1;
public void talk( String name ); static, default or abstract ‫اﻟﻜﻠﻤﺎت‬
public abstract void doProgramming(); ‫ ﻟﻠﻄﺮﻳﻘﺔ ﻓﻘﻂ إذا ﺗﻢ ﺗﻌﺮﻳﻔﻬﺎ‬implement ‫ﻳﻤﻜﻦ ﻋﻤﻞ‬
public abstract void doSpeak(); ‫ ﻓﻼ ﻳﻤﻜﻦ‬abstract ‫ أﻣﺎ اﻟﻄﺮق ﻣﻦ ﻧﻮع‬static or default ‫ﻛـ‬
{
‫أن ﺗﺤﺘﻮي ﻛﻮدات‬
int static speakCount = 2;
} ‫اﻟﻤﺘﻐﻴﺮات ﻏﻴﺮ ﻣﺴﻤﻮح ﺑﻬﺎ ﻓﻲ ﺻﻨﻒ اﻟﻮاﺟﻬﺔ‬
public int number = 1; public ‫ﻛﻞ اﻟﺜﻮاﺑﺖ واﻟﻄﺮق ﻳﺠﺐ أن ﺗﻜﻮن‬
}

public abstract class Car{


(Partially implemented ) Abstract Class ‫ﺻﻨﻒ ﻣﺠﺮد‬ 2
‫ ﺑﺪون أن ﻳﻜﻮن ﻓﻲ داﺧﻠﻪ أي‬abstract ‫اﻟﺼﻨﻒ ﻳﻤﻜﻦ أن ﻳﻜﻮن‬
public static final int wheels = 4; ‫ ﻳﺠﺐ أن‬Methods ‫ ﻟﻜﻦ ﻋﻨﺪﻣﺎ ﻳﻜﻮن ﻓﻴﻪ ﻃﺮق‬Method ‫ﻃﺮﻳﻘﺔ‬
abstract ‫ﺗﻜﻮن واﺣﺪة ﻣﻨﻬﺎ ﻋﻠﻰ اﻷﻗﻞ‬
public String turn( String direction ){
System.out.println( "Turning" + direction ); static ‫ﻳﺴﻤﺢ ﺑﺎﻟﺜﻮاﺑﺖ ﻣﻦ ﻧﻮع‬
}
abstract or concrete ‫ ﺻﻨﻒ‬extend ‫ اﻣﺘﺪاد‬abstract ‫ﻳﻤﻜﻦ ﻟﻠﺼﻨﻒ‬
public abstract void sSound(String sound);
public abstract void shutdown( ); ‫ ﻟﻌﺪة أﺻﻨﺎف واﺟﻬﺔ‬extend ‫واﺣﺪ ﻓﻘﻂ ﻟﻜﻦ ﻳﻤﻜﻨﻪ ﻋﻤﻞ اﻣﺘﺪاد‬
} ‫ ﻫﻮ ﻛــﻼس ﻣــﻦ‬abstract ‫أي ﻛــﻼس ﻣﻜﺘــﻮب ﻗﺒﻠــﻪ ﻛﻠﻤــﺔ‬
‫ أو ﻻ‬Abstract Method‫ ﺑﺼﺮف اﻟﻨﻈﺮ ﻋﻦ إذا وﺟﺪ ﻓﻴﻪ‬abstract ‫ﻧـــﻮع‬

public class Rocket{ (Fully implemented ) Concrete Class ‫ﺻﻨﻒ ﻛﺎﻣﻞ أو ﻣﺘﻤﺎﺳﻚ‬ 3
public static final int astronauts = 4;
String turn( String direction ){ ‫ ﻫﻮ‬Concrete ‫اﻟﺼﻨﻒ‬،‫وﻫﻮ اﻟﺼﻨﻒ اﻟﺬي ﻳﻌﺮﻓﻪ أﻏﻠﺐ اﻟﻤﺒﺮﻣﺠﻴﻦ‬
System.out.println( "Turning" + direction ); ‫ أو اﻻﻣﺘﺪاد ﻣﻨﻪ‬extend ‫ﺻﻨﻒ ﻛﺎﻣﻞ ﺑﺤﺪ ذاﺗﻪ وﻳﻤﻜﻦ اﻣﺘﺪاده‬
} Methods ‫إﻟﻰ أﺻﻨﺎف أﺧﺮى واﺳﺘﺨﺪام ﻃﺮﻗﻪ‬
public abstract void start( String sound ){
System.out.println( "Engines on ");
}
public abstract void shutdown( ){
System.out.println( "Ignitions off !!" );
}
}

29
EVENTS LISTENER ‫ﻣﺴﺘﻤﻊ اﻷﺣﺪاث‬
‫ ﻟﻺﺳﺘﻤﺎع إﻟﻰ اﻷﺣﺪاث اﻟﺘﻲ ﺗﺤﺼﻞ ﻓﻲ اﻟﺘﻄﺒﻴﻖ ﻣﻦ‬Events Listener‫ﺗﺴﺘﺨﺪم‬
‫ أو اﻟﻀﻐﻂ ﺑﺸﻜﻞ ﻣﺴﺘﻤﺮ وﻏﻴﺮﻫﺎ‬،‫ ﻣﺜﻞ اﻟﻀﻐﻂ ﻣﺮة أو ﻣﺮﺗﻴﻦ‬،‫اﻟﻤﺴﺘﺨﺪم‬
‫ ﻋﺮض ﻟﻺﺳﺘﻤﺎع إﻟﻰ‬View ‫ﻳﺠﺐ إﺳﻨﺎده إﻟﻰ ﻋﻨﺼﺮ‬ Listener ‫ﺑﻌﺪ ﺗﺤﺪﻳﺪ اﻟـ‬
‫اﻷﺣﺪاث ﻋﻠﻴﻪ‬
‫ ﻛﻤﺎ ﻫﻮ واﺿﺢ‬View ‫ ﻓﻬﻮ ﻣﻮرث ﻣﻦ اﻟﺼﻨﻒ‬View ‫ﻳﻤﻜﻦ اﺳﺘﺨﺪاﻣﻪ ﻣﻊ أي ﻋﻨﺼﺮ ﻋﺮض‬View.OnClickListener‫اﻟﻜﺎﺋﻦ‬
onClick() ‫ واﺣﺪة وﻫﻲ‬Method ‫وﻳﺤﺘﻮي ﻃﺮﻳﻘﺔ‬
Events Listener ‫ﺗﻌﺮﻳﻒ ﺻﻨﻒ ﻳﺤﻮي‬ 1
public class NumbersClickListener implements OnClickListener {
@Override
public void onClick(View view) {
Toast.makeText(view.getContext(), “Open the list of number”, Toast.LENGTH_SHORT).show();
}
}

constructor ‫ ﺑﺎﺳﺘﺨﺪام اﻟـ‬Object instance of Events Listener ‫ﺗﻌﺮﻳﻒ ﻧﺴﺨﺔ ﻣﻦ اﻟﻜﺎﺋﻦ‬ 2


NumbersClickListerner clickListener = new NumberClickListener();

VIew ‫ إﻟﻰ ﻋﻨﺼﺮ ﻋﺮض‬clickListener ‫إﺳﻨﺎد ﻛﺎﺋﻦ ﻣﺴﺘﻤﻊ اﻷﺣﺪاث‬ 3


Button buttonView = (Button) findViewByID(R.id.button);
‫اﻟـــﺪاﻟﺔ اﻷوﻟﻰ‬
buttonView.setOnClickListener(clickListener);

buttonView.setOnClickListener( new NumberClickListener();); ‫اﻟـــﺪاﻟﺔ اﻟﺜﺎﻧﻴـﺔ‬

buttonView.setOnClickListener(new OnClickListener() {
‫اﻟـــﺪاﻟﺔ اﻟﺜﺎﻟﺜـﺔ‬
@Override
public void onClick(View v) { (‫)اﻟﻤﺨﺘﺼﺮة‬
startActivity(new Intent(MainActivity.this, PhrasesActivity.class)); ‫ﺑﺪل اﻟﺨﻄﻮة‬
} ٢‫ و‬١
});

‫ ﻣﻊ ﺗﻐﻴﻴﺮ اﻟﻤﺤﺘﻮى‬interface class‫ اﻟﻤﻮﺟﻮدة ﻓﻲ اﻟـ‬Method ‫@ ﺗﻌﻨﻲ اﺳﺘﺨــﺪام اﻟﺪاﻟــﺔ‬Override


‫ﺑﻤﺤﺘﻮى آﺧﺮ‬
public interface OnClickListener {
/**
* Called when a view has been clicked.
*
* @param v The view that was clicked.
*/
void onClick(View v);
}

30
‫ﺗﺴﺎؤل؟‬

‫ﻟﻤﺎذا ﻗﻤﻨﺎ ﺑﺎﺳﺘﺨﺪام ‪ OnClickListener‬ﺑﺪﻻ ﻣﻦ اﻟﺴﻄﺮ اﻟﺴﻬﻞ ﻓﻲ ﻛﻮدات ‪android:onClick="myListener" XML‬‬


‫ﺳﻬﻮﻟﺔ ﺗﻐﻴﻴﺮ اﻟﻄﺮﻳﻘﺔ اﻟﺘﻲ ﻳﻌﻤﻞ ﺑﻬﺎ اﻟﺰر‪ .‬ﻳﻤﻜﻦ اﺳﺘﺨﺪام أﺳﻠﻮب ﻣﺨﺘﻠﻒ ﺗﻤﺎ ًﻣﺎ‪ ،‬أو ﺗﻜﺘﻔﻲ ﺑﻤﺠﺮد ﺗﻌﻄﻴﻞ اﻟﺰر‬ ‫‪1‬‬
‫ﻣﻦ ﺧﻼل ﺿﺒﻂ ‪ OnClickListener‬ﻻ ﻳﻘﻮم ﺑﻌﻤﻞ أي ﺷﻲء‬
‫ﺗﺴﻤﺢ ﻟﻚ ﻃﺮﻳﻘﺔ ‪ OnClick‬ﻓﻲ ﺑﺎﻟﺘﺤﻜﻢ ﺑﺎﻟﺰر ﻓﻲ اﻟﻨﺸﺎط اﻟﺤﺎﻟﻲ ﻓﻘﻂ وﻟﻜﻦ ﻫﻨﺎك اﺳﺘﺨﺪاﻣﺎت ﺳﻮف ﺗﺤﺘﺎج أن‬ ‫‪2‬‬
‫ﺗﻜﻮن أواﻣﺮ اﻟﺰر ﺗﻌﻤﻞ ﻓﻲ ﻧﺸﺎﻃﺎت أﺧﺮى ﻛﺬﻟﻚ ﻓﻠﺬﻟﻚ ﻳﺘﻢ اﺳﺘﺨﺪام ‪OnClickListener‬‬

‫اﻟﻤﺼﻔﻮﻓﺎت ‪ARRAY, ARRAYLIST‬‬

‫ﺗﺴﺘﺨﺪم اﻟﻤﺼﻔﻮﻓﺎت ﻋﻨﺪﻣﺎ ﻳﻜﻮن ﻟﺪﻳﻨﺎ ﻋﺪة ﻣﺘﻐﻴﺮات ﻣﻦ ﻧﻔﺲ اﻟﻨﻮع وﻧﺤﺘﺎج إﻟﻰ ﺗﺨﺰﻳﻨﻬﺎ ﺑﺸﻜﻞ ﻣﺘﺘﺎﻟﻲ ﻓﻲ ﻣﺘﻐﻴﺮ‬
‫ﻳﺤﻤﻞ ﻧﻔﺲ اﻹﺳﻢ ؤاﺳﺘﺨﺪام ﻗﻴﻤﺘﻬﺎ ﻓﻲ وﻗﺖ ﻻﺣﻖ‪ ،‬واﻟﻤﺼﻔﻮﻓﺔ ﻫﻲ ﻣﻦ ﻧﻮع ﻛﺎﺋﻦ ‪Object‬‬
‫اﻟﻤﺜﺎل ﺳﻴﻌﺮف ﻣﺼﻔﻮﻓﺔ‬
‫ﻓﻴﻬﺎ ﺛﻼث ﻋﻨﺎﺻﺮ ﻣﻦ‬
‫ﺗﻌﺮﻳﻒ ﻣﺼﻔﻮﻓﺔ ﺟﺪﻳﺪة ;]‪int[] shoeSizes = new int[3‬‬
‫ﻧﻮع ‪int‬‬
‫‪Array Data type‬‬ ‫‪Array‬‬ ‫‪Array Length‬‬
‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫ﻧﻮع ﺑﻴﺎﻧﺎت‬
‫اﻟﻤﺼﻔﻮﻓﺔ‬
‫][‬ ‫‪name‬‬
‫اﺳﻢ‬
‫‪= new‬‬ ‫ﻃــﻮل ﺑﻴﺎﻧـﺎت‬
‫اﻟﻤﺼﻔــــﻮﻓﺔ‬ ‫; ]‪[3‬‬
‫اﻟﻤﺼﻔﻮﻓﺔ‬

‫إﻋﻄﺎء ﻗﻴﻢ ﻣﺒﺪأﻳﺔ ﻟﻌﻨﺎﺻﺮ اﻟﻤﺼﻔﻮﻓﺔ وﻧﻼﺣﻆ أﻧﻨﺎ ﺑﺪأﻧﺎ ﻋﻨﺎﺻﺮ اﻟﻤﺼﻔﻮﻓﺔ ﻣﻦ‬
‫اﻟﺮﻗﻢ ﺻﻔﺮ وﻫﻮ أول ﺧﺎﻧﺔ ﻓﻲ ﻫﺬه اﻟﻤﺼﻔﻮﻓﺔ‬
‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫;‪shoeSizes[0] = 5‬‬
‫‪5 7 10‬‬ ‫;‪shoeSizes[1] = 7‬‬
‫;‪shoeSizes[2] = 10‬‬
‫ﻳﺠﺐ أن ﻳﺮاﻋﻰ أن ﻧﻮع ﺑﻴﺎﻧﺎت اﻟﻤﺼﻔﻮﻓﺔ ﻳﺴﺎوي ﻧﻮع اﻟﺒﻴﺎﻧﺎت ﻟﻠﻘﻴﻢ اﻟﻤﺒﺪأﻳﺔ‬
‫‪0 1‬‬ ‫;]‪String[] namesToStore = new String[2‬‬
‫‪“Ali” 33‬‬ ‫;”‪namesToStore[0] = “Ali‬‬
‫;‪namesToStore[1] = 33‬‬
‫ﻟﻦ ﺗﻜﻮن ﻫﻨﺎ ﻣﺸﻜﻠﺔ إذا ﻟﻢ ﻳﺘﻢ إﻋﻄﺎء ﻗﻴﻤﺔ إﺑﺘﺪاﺋﻴﺔ ﻟﻌﻨﺼﺮ ﻣﺎ ﻓﻲ اﻟﻤﺼﻔﻮﻓﺔ‬
‫ﻟﻜﻦ اﻟﻤﺸﻜﻠﺔ ﺳﺘﺤﺼﻞ ﻋﻨﺪﻣﺎ ﻳﺘﻢ اﺳﺘﺪﻋﺎء ﻗﻴﻤﺔ ﻋﻨﺼﺮ ﻓﺎرغ ﻓﻲ اﻟﻤﺼﻔﻮﻓﺔ‬
‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬ ‫; ]‪int[] numbersToStore = new int[4‬‬
‫‪5 9 ?? 10‬‬ ‫;‪numbersToStore [0] = 5‬‬
‫;‪numbersToStore [1] = 9‬‬
‫;‪numbersToStore [3] = 10‬‬

‫;]‪int itemThree = numbersToStore [3‬‬


‫;]‪int itemtwo = numbersToStore [2‬‬ ‫ﺳﻴﺤﺪث ﺧﻄﺄ ﻫﻨﺎ ﻻوﺟﻮد ﻟﻘﻴﻤﺔ ﻣﺒﺪأﻳﺔ‬

‫‪31‬‬
‫ﺗـﺎﺑــﻊ‬ ‫اﻟﻤﺼﻔﻮﻓﺎت ‪ARRAY, ARRAYLIST‬‬
‫ﻧﺴﺘﺨﺪم ﻗﺎﺋﻤﺔ اﻟﻤﺼﻔﻮﻓﺎت ‪ ArrayList‬ﻋﻨﺪﻣﺎ ﻻ ﻧﻌﺮف ﻃﻮل اﻟﺒﻴﺎﻧﺎت اﻟﺘﻲ ﺳﻨﻀﻌﻬﺎ ﻓﻲ اﻟﻤﺼﻔﻮﻓﺔ وﻫﺬا ﻳﺴﺎﻋﺪ‬
‫ﻋﻠﻰ ﺗﻐﻴﺮ ﺣﺠﻢ اﻟﻤﺼﻔﻮﻓﺔ ﺑﺎﻟﺰﻳﺎدة أو اﻟﻨﻘﺼﺎن ﺣﺴﺐ ﻃﻮل اﻟﺒﻴﺎﻧﺎت‪ ،‬أﻣﺎ ﻓﻲ اﻟﻤﺼﻮﻓﺎت اﻟﻌﺎدﻳﺔ ﻓﻨﺤﻦ ﻣﻠﺰوﻣﻮن‬
‫ﺑﺎﻟﻄﻮل اﻟﺬي ﻧﺤﺪده ﻣﺜﻞ ]‪ int[] number = new int[10‬ﻣﺎذا ﻟﻮ زاد ﻃﻮل اﻟﺒﻴﺎﻧﺎت ﻋﻦ ‪10‬؟‬
‫ﻳﻤﺘﺪ ‪ extends‬ﺗﻌﺮﻳﻒ ﻗﺎﺋﻤﺔ اﻟﻤﺼﻔﻮﻓﺎت ‪ ArrayList‬ﻣﻦ ﺻﻨﻒ ‪ AbstractList‬وﻳﻘﻮم ﻫﺬا اﻟﺼﻨﻒ ﻛﺬﻟﻚ ﺑﺎﻹﻣﺘﺪاد إﻟﻰ‬
‫ﺻﻨﻒ اﻟﻮاﺟﻬﺔ ‪ interface‬واﺳﻤﻪ >‪ List<E‬وﺣﺮف ‪ E‬ﻫﻨﺎ ﻳﺪل ﻋﻠﻰ ﻛﻠﻤﺔ ‪ Element‬وﻳﻌﻨﻲ أن اﻟﺒﻴﺎﻧﺎت اﻟﺘﻲ ﻳﻤﻜﻦ‬
‫وﺿﻌﻬﺎ ﻫﻨﺎ ﻣﻤﻜﻦ ﺗﻜﻮن ﻣﻦ أي ﻧﻮع ﺑﻴﺎﻧﺎت ﻛﺎﺋﻦ وﺑﺪون وﺿﻊ ﻧﻮع ﺑﻴﺎﻧﺎت ﺗﻌﺘﺒﺮ ‪ generic‬وﻋﻨﺪ ﺗﻌﺮﻳﻒ ﻧﻮع ﺑﻴﺎﻧﺎت‬
‫ﻣﻌﻴﻦ ﻓﺈن اﻟﻜﺎﺋﻦ ﻳﻘﻮم ﺑﺎﺳﺘﺒﺪال ﺣﺮف ‪ E‬ﺑﻨﻮع ﺑﻴﺎﻧﺎﺗﺎ اﻟﻌﻨﺎﺻﺮ اﻟﻤﺴﻨﺪة إﻟﻴﻬﺎ‬

‫;)(>‪ArrayList<E> students = new ArrayList<E‬‬ ‫ﻗﺎﺋﻤﺔ ﻣﺼﻔﻮﻓﺔ ﺟﺪﻳﺪة‬

‫;)(>‪ArrayList<String> students = new ArrayList<String‬‬


‫ﻛﺎﺋﻨﺎت ‪ objects‬ﻓﻘﻂ‬
‫ﺣﺬف ﻋﻨﺼﺮ ﻣﺤﺪد‬ ‫اﻟﻮﺻﻮل إﻟﻰ ﻋﻨﺼﺮ ﻣﺤﺪد‬ ‫إﺿﺎﻓﺔ ﻋﻨﺼﺮ ﻟﻘﺎﺋﻤﺔ اﻟﻤﺼﻔﻮﻓﺔ‬

‫;)‪students.remove(2‬‬ ‫;)‪students.get(0‬‬ ‫;)”‪students.add(”Hello‬‬


‫;)‪students.get(2‬‬ ‫;)‪students.add(2,”Welcome‬‬
‫ﻃﻮل ﻗﺎﺋﻤﺔ اﻟﻤﺼﻔﻮﻓــﺔ‬ ‫وﻫﻨﺎ ﻳﺘﻢ إﺿﺎﻓﺔ ﻋﻨﺼﺮ ﻓﻲ ﻣﻜﺎن‬
‫;)(‪students.size‬‬ ‫ﻣﺤﺪد ﻓﻲ ﻫﺬه اﻟﺤﺎﻟﺔ اﻟﺨﺎﻧﺔ‬
‫رﻗﻢ ‪2‬‬

‫ﻣﻘﺎرﻧﺔ ﺑﻴﻦ ‪ Arraylist‬و ‪Array‬‬

‫‪Arraylist‬‬ ‫‪Array‬‬
‫ﻫﻞ ﻳﻤﻜﻦ ﺗﻐﻴﻴﺮ ﻃﻮل اﻟﺒﻴﺎﻧﺎت‬
‫ﻧﻌﻢ‬ ‫ﻻ‬ ‫ﻓﻴﻬﺎ ﺑﻌﺪﻣﺎ ﻳﺘﻢ إﻧﺸﺎءﻫﺎ؟‬

‫ﻧﻌﻢ‬ ‫ﻻ‬ ‫ﻫﻞ ﻫﻲ ﺻﻨﻒ ‪ Class‬؟‬

‫ﺗﺴﺘﺨــﺪم ﻃــﺮق ‪Methods‬‬


‫ﻧﻌﻢ‬ ‫ﻻ‬ ‫ﻟﻠﻮﺻﻮل إﻟﻰ اﻟﻌﻨﺎﺻﺮ وﺗﻐﻴﻴﺮ‬
‫ﻗﻴﻤﻬﺎ؟‬

‫ﻛﺎﺋﻨﺎت ﻓﻘﻂ‬ ‫ﺑﻴﺎﻧﺎت اﻋﺘﻴﺎدﻳﺔ‪int, float,..‬‬ ‫ﻧﻮع اﻟﺒﻴﺎﻧﺎت اﻟﺘﻲ ﻳﻤﻜﻦ‬


‫‪objects only‬‬ ‫وﻛﺎﺋﻨﺎت ‪objects‬‬ ‫ﺗﺨﺰﻳﻨﻬﺎ‬

‫‪32‬‬
‫ﺗـﺎﺑــﻊ‬ ‫اﻟﻤﺼﻔﻮﻓﺎت ‪ARRAY, ARRAYLIST‬‬

‫ﻣﻘﺎرﻧﺔ ﺑﻴﻦ ‪ Arraylist‬و ‪Array‬‬

‫اﻟﺤﻠﻘﺎت اﻟﻤﺴﺘﻤﺮة ‪WHILE, FOR LOOPS‬‬


‫ﺗﻘﻮم اﻟﺤﻠﻘﺎت اﻟﻤﺴﺘﻤﺮة ﺑﺎﺧﺘﺼﺎر اﻟﻮﻗﺖ واﻟﺠﻬﺪ ﺑﺄن ﺗﻜﺮر ﻛﻮد ﻣﺎ ﻋﺪة ﻣﺮات ﺣﺴﺐ ﺗﺤﺪﻳﺪ اﻟﻤﺒﺮﻣﺞ ﻟﻬﺎ وﺳﺘﻜﺮر‬
‫اﻟﻜﻮد ﻓﻲ داﺧﻠﻬﺎ ﻣﻦ دون ﻋﻨﺎء‪ .‬ﺳﻨﺸﺮح ﻧﻮﻋﻴﻦ ﻣﻦ اﻟﺤﻠﻘﺎت اﻟﻤﺴﺘﻤﺮة‬
‫;‪ int count = 0‬ﺗﻌﺮﻳﻒ اﻟﻌﺪاد‬
‫‪While Loop 1‬‬
‫(‪ while‬اﻟﺸـﺮوط‬ ‫‪x‬‬ ‫=<‬ ‫‪5‬‬ ‫{)‬ ‫ﻣﺎداﻣﺖ اﻟﺸﺮوط اﻟﺘﻲ وﺿﻌﺖ ﻓﻲ ﺑﺪاﻳﺔ اﻟﺤﻠﻘﺔ‬
‫;)‪TextView text = new TextView(this‬‬ ‫ﺻﺤﻴﺤﺔ ﻓﺈن اﻟﻜﻮد داﺧﻞ ‪ loop‬ﺳﻴﺘﻜﺮر إﻟﻰ أن اﻟﻰ ان‬
‫اﻟﻜﻮد اﻟﻤﻜﺮر‬
‫;)”‪text.setText(”Hello‬‬ ‫ﻳﺘﺤﻘﻖ اﻟﺸﺮط ﺑﺼﺮف اﻟﻨﻈﺮ ﻋﻦ ﻧﻮع اﻟﺸﺮط أو ﻃﺮﻳﻘﺔ‬
‫;‪ x = x + 1‬ﺗﺤﺪﻳﺚ اﻟﻌﺪاد‬ ‫ﻛﺘﺎﺑﺘﻪ‪ ،‬وﻫﺬا ﺑﻼ ﺷﻜﻞ ﻳﺴﺎﻋﺪ ﻓﻲ إﺧﺘﺼﺎر اﻟﻜﺜﻴﺮ ﻣﻦ‬
‫}‬ ‫اﻟﻜﻮدات اﻟﻤﺘﻜﺮرة‬
‫اﺳﺘﺨﺪام اﻟﺤﻠﻘﺔ ‪ while‬ﻟﻄﺒﺎﻋﺔ ﻗﺎﺋﻤﺔ اﻟﻤﺼﻔﻮﻓﺎت ﻋﻠﻰ اﻟﺸﺎﺷﺔ‬
‫ﻣﺼﻔﻮﻓﺔ ﺟﺪﻳﺪة‬ ‫;)(>‪ArrayList<String> words = new ArrayList<String‬‬
‫إﺿﺎﻓﺔ ﻋﻨﺼﺮ ﻟﻠﻤﺼﻔﻮﻓﺔ‬ ‫;)"‪words.add("one‬‬
‫إﺿﺎﻓﺔ ﻋﻨﺼﺮ ﻟﻠﻤﺼﻔﻮﻓﺔ‬ ‫;)"‪words.add("two‬‬
‫إﺿﺎﻓﺔ ﻋﻨﺼﺮ ﻟﻠﻤﺼﻔﻮﻓﺔ‬ ‫;)"‪words.add("three‬‬

‫;)‪ LinearLayout rootView = (LinearLayout) findViewById(R.id.rootView‬ﺗﻌﺮﻳﻒ ﺗﺨﻄﻴﻂ ﻋﺮض أب‬


‫;‪ int index = 0‬ﺗﻌﺮﻳﻒ اﻟﻌﺪاد‬
‫اﻟﻌﺪاد ﻳﻜﻮن أﻗﻞ ﻣﻦ ﻃﻮل ﻋﻨﺎﺻﺮ اﻟﻤﺼﻔﻮﻓﺔ )أﻗﻞ ﻣﻦ ‪ while (index < words.size()) { (3‬ﺗﻌﺮﻳﻒ ﺣﻠﻘﺔ ‪ while‬ﺟﺪﻳﺪة‬
‫;)‪ TextView wordView = new TextView(this‬ﺗﻌﺮﻳﻒ ﻋﻨﺼﺮ ﻋﺮض ﻧﺺ ﺟﺪﻳﺪ‬ ‫ﻧﺎﺗﺞ اﻟﻜﻮد‬
‫;))‪ wordView.setText(words.get(index‬ﺗﻐﻴﺮ اﻟﻨﺺ إﻟﻰ ﻋﻨﺼﺮ اﻟﻤﺼﻔﻮﻓﺔ‬ ‫‪one‬‬
‫;)‪ rootView.addView(wordView‬إﺿﺎﻓﺔ ﻋﻨﺼﺮ اﻟﻨﺺ إﻟﻰ اﻟﺘﺨﻄﻴﻂ‬ ‫‪two‬‬
‫;‪ index++‬ﺗﺤﺪﻳﺚ ﻗﻴﻤﺔ اﻟﻌﺪاد زﻳﺎدﺗﻬﺎ ﺑـ ‪1‬‬ ‫‪three‬‬
‫}‬
‫ﻟﻤﻌﻠﻮﻣﺎت أﻛﺜﺮ ﻋﻦ اﻟﻔﺮق‬
‫‪https://macdiscussions.udacity.com/t/while-loop-and-for-loop/91988‬‬ ‫ﺑﻴﻦ ‪ For‬و ‪While‬‬

‫‪33‬‬
‫ﺗـﺎﺑــﻊ‬ ‫اﻟﺤﻠﻘﺎت اﻟﻤﺴﺘﻤﺮة ‪WHILE, FOR LOOPS‬‬

‫; ﺗﻌﺮﻳﻒ اﻟﻌﺪاد( ‪for‬‬ ‫{ ) ﺗﺤﺪﻳﺚ اﻟﻌﺪاد ; اﻟﺸــﺮوط‬ ‫‪For Loop 2‬‬


‫ﺗﺴﺘﺨﺪم ﻋﺎدة اﻟـ ‪ For‬ﻟﻌﻤﻞ اﻟﺤﻠﻘﺎت اﻟﻤﺘﻜﺮرة وإﻋﺎدة ﻛﺘﺎﺑﺔ‬
‫اﻟﻜﻮد اﻟﻤﻜﺮر‬
‫ﺣﻠﻘﺔ ‪ while‬ﻟﺘﺼﺒﺢ أﻗﺼﺮ وأﻛﺜﺮ إﺣﻜﺎﻣﺎ‬
‫}‬ ‫ﻧﺎﺗﺞ اﻟﻜﻮد‬
‫‪Index:0 Value:one‬‬
‫{ )‪for (int index = 0; index < 3; index++‬‬ ‫‪Index:1 Value:two‬‬
‫;))‪Log.v(“NumbersActivity”, “Index: “ + index + “ Value: “ + words.get(index‬‬ ‫‪Index:2 Value:three‬‬
‫}‬
‫اﻟﻤﺜﺎل ﻓﻲ اﻷﻋﻠﻰ ﻳﻘﻮم ﺑﺘﻌﺮﻳﻒ ﻋﺪاد اﺳﻤﻪ ‪ index‬وﻳﻌﻄﻴﻪ ﻗﻴﻤﺔ اﺑﺘﺪاﺋﻴﺔ ‪ 0‬وﺛﻢ ﻳﺘﻢ اﻟﺘﺤﻘﻖ ﻣﻦ اﻟﺸﺮط وﻓﻲ‬
‫ﻫﺬه اﻟﺤﺎﻟﺔ اﻟﻌﺪاد ﻳﺠﺐ أن ﻳﻜﻮن أﻗﻞ ﻣﻦ ‪ 3‬وﺛﻢ ﻳﺘﻢ ﺗﻄﺒﻴﻖ اﻟﻜﻮد داﺧﻞ اﻟﺤﻠﻘﺔ وﺑﻌﺪﻫﺎ ﻳﺘﻢ زﻳﺎدة ﻗﻴﻤﺔ اﻟﻌﺪاد أو‬
‫إﻧﻘﺎﺻﻪ وﻓﻲ اﻟﻤﺜﺎل ﺗﻢ زﻳﺎدة اﻟﻌﺪاد ﺑﻮاﺣﺪ‪ .‬ﻓﻲ اﻟﻨﻬﺎﻳﺔ ﺗﻨﺘﻬﻲ اﻟﺤﻠﻘﺔ إذا أﺻﺒﺢ اﻟﺸﺮط اﻟﻤﺤﺪد ﺧﻄﺄ وﻓﻲ اﻟﻤﺜﺎل‬
‫ﺳﻴﻜﻮن اﻟﻌﺪاد أﻛﺒﺮ ﻣﻦ أو ﻳﺴﺎوي ‪ 3‬ﻟﺼﺒﺢ اﻟﺸﺮط ﺧﻄﺄ‬
‫&& و‬ ‫< أﺻﻐﺮ ﻣﻦ‬ ‫> أﻛﺒﺮ ﻣﻦ‬ ‫اﻟﺸﺮوط ‪ conditions‬ﺗﻘﺒﻞ == ﻳﺴﺎوي‬
‫|| أو‬ ‫=! ﻻ ﻳﺴﺎوي => أﻛﺒﺮ ﻣﻦ أو ﻳﺴﺎوي =< أﺻﻐﺮ ﻣﻦ أو ﻳﺴﺎوي‬ ‫ﻋﻮاﻣــﻞ اﻟﻤﻘـﺎرﻧﺔ اﻟﺘﺎﻟﻴﺔ‬

‫ﻣﻮارد اﻟﺬاﻛﺮة اﻟﻤﺤﺪودة ‪LIMITED MEMORY RESOURCES‬‬


‫ﻷن ﻣﻮارد اﻟﺬاﻛﺮة ﻓﻲ أﺟﻬﺰة اﻷﻧﺪرﻳﻮد ﻣﺤﺪودة ﻓﺎﻟﻌﻨﺎﺻﺮ اﻟﺘﻲ ﻧﻈﻬﺮﻫﺎ ﻋﻠﻰ اﻟﺸﺎﺷﺔ ﻳﺠﺐ‬
‫أن ﻻ ﺗﺄﺧﺬ ﺣﻴﺰا ﻛﺒﻴﺮا ﻣﻦ اﻟﻤﻮارد ﺧﺼﻮﺻﺎ وأن ﺗﻄﺒﻴﻘﻨﺎ ﺳﻴﺸﺎرﻛﻪ ﻓﻲ ﻣﻮارد اﻟﺬاﻛﺮة ﺗﻄﺒﻴﻘﺎت‬
‫أﺧﺮى ﻓﻲ ﻧﻔﺲ اﻟﺠﻬﺎز ﻛﺬﻟﻚ‪ .‬ﻓﻠﻮ ﻣﺜﻼ ﻛﺎن ﻟﺪﻳﻨﺎ ‪ 1000‬ﻋﻨﺼﺮ ﻋﺮض ﻧﺮﻳﺪ ﻋﺮﺿﻬﺎ ﻓﻲ‬
‫اﻟﺸﺎﺷﺔ ﻓﻬﺬا ﺑﻼ ﺷﻚ ﺳﻴﺄﺧﺬ ﺣﻴﺰا ﻛﺒﻴﺮا ﻣﻦ اﻟﺬاﻛﺮة ﺧﺼﻮﺻﺎ إذا ﻛﺎن ﻫﻨﺎك ﺻﻮر ﻳﺠﺐ ﻋﺮﺿﻬﺎ‬
‫ﻟﺘﻔﺎدي ﻫﺬه اﻟﻤﺸﻜﻠﺔ ﻧﺴﺘﻄﻴﻊ اﺳﺘﺨﺪام اﺳﻠﻮب إﻋﺎدة ﺗﺪوﻳﺮ اﻟﻌﺮض وذﻟﻚ ﺑﺄن ﻳﺘﻢ ﻋﺮض‬
‫اﻟﻌﻨﺎﺻﺮ اﻟﺘﻲ ﺗﻈﻬﺮ ﻟﻠﻤﺴﺘﺨﺪم ﻓﻘﻂ وﺑﺎﻗﻲ ﻋﻨﺎﺻﺮ اﻟﻌﺮض ﺗﻜﻮن ﻣﻮﺟﻮدة ﻣﺤﻔﻮﻇــﺔ‬
‫ﻓــﻲ ‪ ArrayAdapter‬ﻳﺤﻔــﻆ ﻣﻌﻠﻮﻣــﺎت ﻫــﺬه اﻟﻌﻨــﺎﺻﺮ وﻳﻈﻬــﺮﻫﺎ ﻓـﻲ اﻟﺸـﺎﺷــﺔ إذا‬
‫ﻗﺎم اﻟﻤﺴﺘﺨﺪم ﺑﺘﺤﺮﻳﻚ اﻟﻘﺎﺋﻤﺔ إﻟﻰ أﻋﻠﻰ أو أﺳﻔﻞ‬

‫ﻋﻨﺼﺮ ﻋﺮض إﻋﺎدة اﻟﺘﺪوﻳﺮ ‪VIEW RECYCLING‬‬


‫ﺳﻨﺴﺘﺨﺮم ﻓﻲ ﻣﺜﺎﻟﻨﺎ ﻹﻋﺎدة ﺗﺪوﻳﺮ اﻟﻌﺮض ﻋﻨﺼﺮﻳﻦ‬
‫‪ArrayAdapter + ListView‬‬
‫ﻳﺘﻢ ﺗﺤﻤﻴﻞ ﻗﺎﺋﻤﺔ اﻟﻌﻨﺎﺻﺮ ﻓﻲ ‪ArrayAdapter‬‬ ‫‪1‬‬
‫ﻳﻠﺤﻖ اﻟـ‪ ArrayAdapter‬إﻟﻰ ﻗﺎﺋﻤﺔ ‪Listview‬‬ ‫‪2‬‬
‫ﻳﺴﺘﺨﺪم ‪ Listview‬ﻓﻘﻂ اﻟﻌﻨﺎﺻﺮ اﻟﺘﻲ ﺗﻈﻬﺮ ﻟﻠﻤﺴﺘﺨﺪم‬ ‫‪3‬‬
‫ﻋﻨﺪ ﺗﺤﺮﻳﻚ اﻟﻤﺴﺘﺨﺪم ﻋﻨﺎﺻﺮ اﻟﻘﺎﺋﻤﺔ ﺗﺨﺘﻔﻲ اﻟﻌﻨﺎﺻﺮ ﻓﻲ اﻷﺳﻔﻞ أو اﻷﻋﻠﻰ )ﺣﺴﺐ اﺗﺠﺎه اﻟﺘﺤﺮﻳﻚ( ﻓﺘﻨﺘﻘﻞ‬ ‫‪4‬‬
‫ﻫﺬه اﻟﻌﻨﺎﺻﺮ اﻟﻤﺨﻔﻴﺔ إﻟﻰ ‪ Scrap View‬وﻳﺘﻢ إﺿﺎﻓﺔ ﻋﻨﺎﺻﺮ أﺧﺮى ﻣﻜﺎﻧﻬﺎ وإذا اﻧﻌﻜﺲ اﻻﺗﺠﺎه ﻓﻲ اﻟﺘﺤﺮﻳﻚ ﻳﺘﻢ‬
‫إرﺟﺎع ﻫﺬه اﻟﻌﻨﺎﺻﺮ ﻣﻦ ‪ Scrap View‬إﻟﻰ ﻗﺎﺋﻤﺔ ‪ ListVIew‬ﻟﻌﺮﺿﻬﺎ ﻣﺮة أﺧﺮى‬

‫اﺳﺘﺨﺪام ‪ ListVIew‬ﻳﻘﻠﻞ ﻣﻦ اﺳﺘﺨﺪام ﻣﻮارد اﻟﺬاﻛﺮة إذا ﻣﺎ ﻗﺎرﻧﺎه ﻟﻮ ﻛﺮرﻧﺎ ﻫﺬه اﻟﻌﻨﺎﺻﺮ ﻓﻲ ﻣﻠﻒ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ ‪XML‬‬

‫‪34‬‬
A NEED FOR VIEW RECYCLING? ‫ﻫﻞ ﺗﺤﺘﺎج إﻟﻰ ﻋﻨﺼﺮ ﻋﺮض إﻋﺎدة اﻟﺘﺪوﻳﺮ؟‬

Setting Activity

‫ﻻ‬ ‫ﻧﻌﻢ‬ ‫ﻻ‬ ‫ﻧﻌﻢ‬ ‫ﻻ‬ ‫ﻧﻌﻢ‬ ‫ﻻ‬ ‫ﻧﻌﻢ‬

LISTVIEW + ARRAYADAPTER

‫ ﺑﺎﺳﺘﺨﺪام اﻟﻨﻤﻂ اﻟﻄﺒﻴﻌﻲ ﻟﻠﻘﺎﺋﻤﺔ ﺳﻨﺴﺘﺨﺪم ﻫﺬه اﻟﺨﻄﻮات‬ArrayAdapter ‫ ﻣﻊ‬ListView ‫ﻹﻧﺸﺎء ﻗﺎﺋﻤﺔ‬
word_list.xml ‫ اﻟﺨﺎص ﺑﺎﻟﻘﺎﺋﻤﺔ‬XML ‫إﺿﺎﻓﺔ ﻣﻠﻒ‬ 1
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
‫ اﺳﺘﺨﺪام ﻋﻨﺼﺮ‬ListView ‫ﺑﻄﺒﻴﻌﺔ اﻟﻘﺎﺋﻤﺔ‬
xmlns:tools="http://schemas.android.com/tools"
‫ وﻳﻤﺜﻞ‬TextView ‫ﻋﺮض واﺣﺪ ﻓﻘﻂ ﻣﻦ ﻧﻮع‬
android:id="@+id/list"
‫اﻟﻌﻨﺎﺻﺮ اﻟﺘﻲ ﺳﻴﺘﻢ ﻋﺮﺿﻬﺎ واﻟﺘﻲ ﻓﻲ‬
android:orientation="vertical"
words ‫ﻣﺜﺎﻟﻨﺎ ﻫﺬا ﻫﻲ ﻋﻨﺎﺻﺮ اﻟﻤﺼﻔﻮﻓﺔ‬
android:layout_width="match_parent"
android.R.layout.simple_list_item_1 ‫و‬
android:layout_height="match_parent"
‫ﻫﻮ ﻋﻨﺼﺮ اﻟﺘﺨﻄﻴﻂ اﻟﺬي ﺑﺪاﺧﻠﻪ ﻋﻨﺼﺮ‬
/>
TextView ‫ﻋﺮض واﺣﺪ ﻓﻘﻂ‬
Activity ‫إﺿﺎﻓﺔ أﻛﻮاد ﺟﺎﻓﺎ إﻟﻰ اﻟﻤﻠﻒ‬ 2
Constructor
ArrayAdapter<String> itemsAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, words);
ListView listView = (ListView) findViewById(R.id.list);
listView ‫ ﻟﻠﻘﺎﺋﻤﺔ‬ArrayAdapter ‫ﻳﺘﻢ ﻫﻨﺎ ﺗﻌﺮﻳﻒ‬
listView.setAdapter(itemsAdapter);

RecyclerView ‫و‬GridView ‫ و‬ListView ‫ ﻣﻊ‬ArrayAdapter ‫ﻧﺴﺘﻄﻴﻊ اﺳﺘﺨﺪام اﺳﻠﻮب ﻋﺮض اﻟﻌﻨﺎﺻﺮ‬


‫ ﺳﻴﺴﺘﺨﺪم ﻣﺮﺑﻊ ﻧﺺ واﺣﺪ ﻟﻌﺮض اﻟﻤﺼﻔﻮﻓﺔ ﻓﻲ اﻟﻘﺎﺋﻤﺔ‬android.R.layout.simple_list_item_1

XML ‫ﻣﻠﻒ‬ ‫ ﻳﺠﺐ أن ﻧﻌﻤﻞ‬،‫ﻟﻌﻤﻞ ﺗﺨﻄﻴﻂ ﻣﺨﺼﺺ ﻟﻌﺮض اﻟﻤﺼﻔﻮﻓﺔ ﻣﺜﻼ ﻛﻤﺎ ﻓﻲ اﻟﺸﻜﻞ أدﻧﺎه‬
‫ وﻻ ﻧﻨﺴﻰ إﻋﻄﺎء‬،‫وﻧﻀﻊ ﻓﻴﻪ اﻟﻌﻨﺎﺻﺮ اﻟﺘﻲ ﻧﺮﻳﺪﻫﺎ أن ﺗُﻈﻬﺮ اﻟﻤﺼﻔﻮﻓﺔ ﺑﺎﻟﺸﻜﻞ اﻟﺬي ﻧﺮﻳﺪه‬
‫اﺳﻢ ﻣﻌﺮف ﻟﻜﻞ ﻣﺮﺑﻊ ﻧﺺ ﻟﻠﺮﺟﻮع إﻟﻴﻪ ﻓﻲ ﻛﻮدات ﺟﺎﻓﺎ‬

35
CUSTOM CLASS ‫ﺻﻨﻒ ﻣﺨﺼﺺ‬

‫ وﻟﺘﻤﺮﻳﺮ ﻣﺼﻔﻮﻓﺘﻴﻦ ﻣﻦ اﻟﻜﻠﻤﺎت‬Miwok‫ﻛﻠﻤﺎت ﺑﺎﻟﻠﻐﺔ اﻹﻧﺠﻠﻴﺰﻳﺔ وﻛﻠﻤﺎت ﺑﺎﻟﻠﻐﺔ‬،‫ ﻟﺪﻳﻨﺎ ﻗﺎﺋﻤﺘﻴﻦ‬Miwok ‫ﻓﻲ اﻟﻤﺸﺮوع‬
‫ ﻣﺨﺼﺺ ﺣﺘﻰ‬Class ‫ ﻣﺨﺼﺺ ﻟﻜﻦ ﻗﺒﻞ ذﻟﻚ ﻧﺤﺘﺎج أن ﻧﻌﻤﻞ ﺻﻨﻒ‬ArrayAdapter ‫ ﺳﻨﺤﺘﺎج إﻟﻰ‬ListView ‫إﻟﻰ‬
‫ وﻣﺘﻐﻴﺮات ﺗﻤﻜﻨﻨﺎ ﻣﻦ ﺗﻀﻤﻴﻦ اﻟﻤﻌﻠﻮﻣﺎت وﺗﺠﻤﻴﻌﻬﺎ ﻓﻲ ﺻﻨﻒ واﺣﺪ ﻣﺤﺪد‬Methods ‫ﻧﺘﺤﻔﻆ ﻓﻴﻪ ﺑﻄﺮق‬
WordsAdapter.java ‫ و‬Words.java ‫إﻧﺸﺎء ﻣﻠﻔﺎت ﺟﺪﻳﺪة ﺑﺎﺳﻢ‬ 1

WordsAdapter.java ‫ﻛﺘﺎﺑﺔ أﻛﻮاد‬ 3 Words.java ‫ﻛﺘﺎﺑﺔ أﻛﻮاد‬ 2


package com.example.android.miwok;
package com.example.android.miwok;
public class WordAdapter extends ArrayAdapter<Word> {
public class Word {
/**‫* ﻛﻮﻧﺴﺘﺮاﻛﺘﻮر ﺧﺎص ﻟﻬﺬا اﻷدﺑﺘﻮر ﻹﺳﺘﺨﺪاﻣﻪ ﺧﺎرج اﻟﺼﻨﻒ‬/
/**‫* ﻣﺘﻐﻴﺮ ﻟﻠﺘﺮﺟﻤﺔ اﻹﻓﺘﺮاﺿﻴﺔ ﻟﻠﻜﻠﻤﺔ‬/
public WordAdapter(Activity context, ArrayList<Word> word) {
private String mDefaultTranslation;
super(context, 0, word);
/**‫* ﻣﺘﻐﻴﺮ ﻟﻠﺘﺮﺟﻤﺔ ﺑﻠﻐﺔ ﻣﺎﻳﻮوك ﻟﻠﻜﻠﻤﺔ‬/
}
private String mMiwokTranslation;
@NonNull
@Override
/**
/**‫* اﻟﻄﺮﻳﻘﺔ اﻟﺨﺎص ﺑﺘﺤﻮﻳﻞ ﻋﻨﺎﺻﺮ اﻟﻌﺮض إﻟﻰ اﻟﺘﺨﻄﻴﻂ اﻟﻤﻄﻠﻮب ﻣﻌﻬﺎ ﻋﻨﺎﺻﺮ اﻟﻤﺼﻔﻮﻓﺔ‬/
‫ﺗﺴﻤﻰ ﻫﺬه اﻟﻄﺮﻳﻘﺔ ﻛﻮﻧﺴﺘﺮاﻛﺘﻮر‬
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
‫وﺗﺴﺘﺨﺪم ﻹﻳﺼﺎل اﻟﻤﺘﻐﻴﺮات ﻣﻦ ﺧﺎرج اﻟﺼﻨﻒ إﻟﻰ داﺧﻠﻪ‬
View listItemView = convertView;
*/
if (listItemView == null) {
public Word(String defaultTrans, String miwokTrans) {
listItemView = LayoutInflater.from(getContext()).inflate(
mDefaultTranslation = defaultTrans;
R.layout.list_item, parent, false);
mMiwokTranslation = miwokTrans;
}
}
/**‫* اﺧﺘﻴﺎر ﻋﻨﺼﺮ ﻣﻦ اﻟﻤﺼﻔﻮﻓﺔ ﻟﻌﺮﺿﺔ ﺣﺴﺐ ﻣﻜﺎن اﻟﻌﻨﺼﺮ‬/
Word currentWord = getItem(position);
/**‫* اﻟﺤﺼﻮل ﻋﻠﻰ اﻟﺘﺮﺟﻤﺔ اﻹﻓﺘﺮاﺿﻴﺔ ﻟﻠﻜﻠﻤﺔ‬/
/**‫*ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﺮات ﻟﻌﻨﺎﺻﺮ اﻟﻌﺮض ﻣﻦ ﻧﻮع ﻧﺺ اﻟﻤﻮﺟﻮدة ﻓﻲ ﻧﻔﺲ اﻟﺘﺨﻄﻴﻂ‬/
public String getDefaultTranslation() {
TextView miwokTextView = (TextView) listItemView.findViewById(R.id.miwok_text_view);
return mDefaultTranslation;
TextView defaultTextView = (TextView) listItemView.findViewById(R.id.default_text_view);
}
/**‫*ﺗﻐﻴﻴﺮ اﻟﻨﺺ ﻟﻌﻨﺼﺮ اﻟﻌﺮض ﺣﺴﺐ ﺑﻴﺎﻧﺎت اﻟﻤﺼﻔﻮﻓﺔ اﻟﺤﺎﻟﻴﺔ ﺣﺴﺐ ﺗﺮﺗﻴﺒﻬﺎ‬/
miwokTextView.setText(currentWord.getMiwokTranslation());
/**‫* اﻟﺤﺼﻮل ﻋﻠﻰ اﻟﺘﺮﺟﻤﺔ ﺑﻠﻐﺔ ﻣﺎﻳﻮوك ﻟﻠﻜﻠﻤﺔ‬/
defaultTextView.setText(currentWord.getDefaultTranslation());
public String getMiwokTranslation() {
/** ‫*إرﺟﺎع ﻋﻨﺼﺮ ﻋﺮض ﻣﺨﻄﻂ اﻟﻘﺎﺋﻤﺔ اﻟﻜﺎﻣﻠﺔ ﻓﻴﻬﺎ ﻣﺮﺑﻌﻴﻦ ﻧﺺ ﻟﻌﺮض ﻓﻲ اﻟﻘﺎﺋﻤﺔ‬/
return mMiwokTranslation;
return listItemView;
}
}
}
}

36
‫ﺗﺎﺑــﻊ‬ CUSTOM CLASS ‫ﺻﻨﻒ ﻣﺨﺼﺺ‬

‫ﻛﻠﻤﺎت ﺑﺎﻟﻠﻐﺔ‬،‫ ﻟﺪﻳﻨﺎ ﻗﺎﺋﻤﺘﻴﻦ‬Miwok ‫ﻓﻲ اﻟﻤﺸﺮوع‬ list_item.xml ‫إﻧﺸﺎء ﻣﻠﻒ ﺟﺪﻳﺪﺑﺎﺳﻢ‬ 4
‫ وﻟﺘﻤﺮﻳﺮ ﻣﺼﻔﻮﻓﺘﻴﻦ‬Miwok ‫اﻹﻧﺠﻠﻴﺰﻳﺔ وﻛﻠﻤﺎت ﺑﺎﻟﻠﻐﺔ‬ <?xml version="1.0" encoding="utf-8"?>
‫ ﻣﺨﺼﺺ‬ArrayAdapter ‫ﻣﻦ اﻟﻜﻠﻤﺎت إﻟﻰ ﺳﻨﺤﺘﺎج إﻟﻰ‬ <LinearLayout
‫ ﻣﺨﺼﺺ‬Class ‫ﻟﻜﻦ ﻗﺒﻞ ذﻟﻚ ﻧﺤﺘﺎج أن ﻧﻌﻤﻞ ﺻﻨﻒ‬ xmlns:android="http://schemas.android.com/apk/res/android"
‫ وﻣﺘﻐﻴﺮات ﺗﻤﻜﻨﻨﺎ‬Methods ‫ﺣﺘﻰ ﻧﺘﺤﻔﻆ ﻓﻴﻪ ﺑﻄﺮق‬ xmlns:tools="http://schemas.android.com/tools"
‫ﻣﻦ ﺗﻀﻤﻴﻦ اﻟﻤﻌﻠﻮﻣﺎت وﺗﺠﻤﻴﻌﻬﺎ ﻓﻲ ﺻﻨﻒ واﺣﺪ‬ android:layout_width="match_parent"
‫ﻣﺤﺪد‬ android:orientation="vertical"
android:layout_height="match_parent">
‫ ﺑﺪل‬ListView ‫ﺳﻴﺘﻢ اﺳﺘﺨﺪام ﻫﺬا اﻟﻜﻮد ﻟﻌﻨﺎﺻﺮ اﻟﻘﺎﺋﻤﺔ‬
‫ﻣﺮﺑﻊ اﻟﻨﺺ اﻹﻓﺘﺮاﺿﻲ اﻟﺬي ﻳﻈﻬﺮ ﻓﻴﻬﺎ ﺳﻴﻜﻮن ﻫﺬا‬ <TextView
‫اﻟﺘﺼﻤﻴﻢ ﻣﺨﺼﺺ‬ android:id="@+id/miwok_text_view"
android:layout_width="match_parent"
android:layout_height="44dp"
‫ﺗﺴﺘﺨﺪم ﻫﺬه اﻟﻤﻴﺰة ﻟﺘﺒﺪﻳﻞ اﻟﻨﺺ اﻟﻈﺎﻫﺮ ﻓﻲ ﺷﺎﺷﺔ‬ android:textAppearance="?android:textAppearanceMedium"
‫ وﻫﺬا‬،‫اﻟﻤﻌﺎﻳﻨﺔ اﻟﺘﻲ ﺗﻈﻬﺮ ﻓﻲ اﻷﻧﺪرﻳﻮد اﺳﺘﻮدﻳﻮ‬ tools:text="lutti" />
‫ﻳﻌﻄﻲ ﻳﺴﻬﻞ اﻟﻌﻤﻞ ﻋﻠﻰ ﺗﺼﻤﻴﻢ اﻟﻮاﺟﻬﺔ‬
Placeholder ‫وﻳﺠﻌﻠﻬﺎ أﻛﺜﺮ واﻗﻌﻴﺔ وﻳﺴﻤﻰ‬ <TextView
android:id="@+id/default_text_view"
android:layout_width="match_parent"
android:layout_height="44dp"
android:textAppearance="?android:textAppearanceMedium"
tools:text="one" />
</LinearLayout>

‫ ﺳﻴﺘﻢ‬Method ‫ﻓﻲ ﻛﻮدات اﻟﻨﺸﺎط داﺧﻞ اﻟﻄﺮﻳﻘﺔ‬ ‫ اﻟﻤﺨﺼﺺ‬ArrayAdapter ‫إﺿﺎﻓﺔ أﻛﻮاد اﻟـ‬ 5
‫إﺿﺎﻓﺔ ﻫﺬه اﻷﻛﻮاد أوﻻ ﺳﻴﺘﻢ إﻧﺸﺎء ﻗﺎﺋﻤﺔ اﻟﻜﻠﻤﺎت‬
‫ وﺛﻢ إﺿﺎﻓﺔ وﺗﻌﺮﻳﻒ ﻣﺼﻔﻮﻓﺔ‬ArrayList ‫ﺑﺎﺳﺘﺨﺪام‬ /**‫* إﻧﺸﺎء ﻗﺎﺋﻤﺔ ﺑﺎﻟﻜﻠﻤﺎت‬/
ArrayList<Word> words = new ArrayList<Word>();
‫ وﻻﺑﺪ ﻛﺬﻟﻚ ﻣﻦ ﺗﺤﺪﻳﺪ‬،‫ﺟﺪﻳﺪة ﻣﻦ اﻟﺼﻨﻒ اﻟﻤﺨﺼﺺ‬
words.add(new Word("one", "lutti"));
‫اﻟﻘﺎﺋﻤﺔ اﻟﺘﻲ ﺳﻴﻌﻤﻞ ﻋﻠﻴﻬﺎ اﻷدﺑﺘﻮر اﻟﺨﺎص ﺣﺘﻰ‬
words.add(new Word("two", "otiiko"));
‫ﻧﺴﻨﺪ اﻷدﺑﺘﻮر اﻟﺬي ﺟﻬﺰﻧﺎه إﻟﻲ أدﺑﺘﻮر اﻟﻘﺎﺋﻤﺔ‬ words.add(new Word("three", "tolookosu"));

/**‫* إﻧﺸﺎء ﻗﺎﺋﻤﺔ ﻣﻦ اﻟﻤﺼﻔﻮﻓﺔ ﺑﺎﺳﺘﺨﺪام اﻷدﺑﺘﻮر اﻟﻤﺨﺼﺺ‬/


‫ﻣﻠﺨﺺ اﻟﻤﻠﻔﺎت اﻟﺘﻲ ﺗﻢ اﺳﺘﺨﺪاﻣﻬﺎ ﻟﻸدﺑﺘﻮر‬ WordAdapter adapter = new WordAdapter(this, words);
1 word_list.xml /**‫*ﺗﻌﺮﻳﻒ اﻟﻘﺎﺋﻤﺔ اﻟﺘﻲ ﺳﻴﺘﻢ ﻋﺮض ﺑﻴﺎﻧﺎت اﻷدﺑﺘﻮر ﻋﻠﻴﻬﺎ‬/
ListView listView = (ListView) findViewById(R.id.list);
2 Words.java /**‫*اﺳﺘﺨﺪام اﻷدﺑﺘﻮر اﻟﻤﺨﺼﺺ ﻟﻌﺮض اﻟﺒﻴﺎﻧﺎت ﻋﻠﻰ اﻟﻘﺎﺋﻤﺔ‬/
listView.setAdapter(adapter);
3 WordsAdapter.java
4 list_item.xml

37
STEPS TO MODIFY AN APP ‫ﺧﻄﻮات اﻟﺘﻌﺪﻳﻞ ﻋﻠﻰ ﺗﻄﺒﻴﻖ‬

،‫ﻓﻲ أﻏﻠﺐ اﻟﺤﺎﻻت ﺳﺘﺄﺗﻴﻚ ﺗﻄﺒﻴﻘﺎت ﻳﻄﻠﺐ ﻣﻨﻚ ﺗﻄﻮﻳﺮﻫﺎ ﻓﻬﻨﺎك ﻋﺪة ﺧﻄﻮات ﻟﺬﻟﻚ ﺳﺘﺴﻬﻞ ﻋﻠﻴﻚ اﻟﻤﻬﻤﺔ‬
‫ اﻟﻤﻄﻠﻮب ﻫﻮ إﺿﺎﻓﺔ اﻟﺼﻮر إﻟﻲ اﻟﺘﻄﺒﻴﻖ وﻋﺮض ﻟﻜﻞ ﻧﻮع ﻣﻦ اﻟﻜﻠﻤﺎت ﻓﻲ اﻟﻘﺎﺋﻤﺔ‬Miwok ‫ﻓﻲ اﻟﻤﺸﺮوع‬

Edit Layout file ‫اﻟﺘﻌﺪﻳﻞ ﻋﻠﻰ ﻣﻠﻒ اﻟﺘﺨﻄﻴﻂ‬ 1


Edit Layout file ‫ﻓﻔﻲ ﺣﺎﻟﺘﻨﺎ ﻣﻠﻒ اﻟﺘﺨﻄﻴﻂ اﻟﺬي ﻳﺤﺘﺎج إﻟﻲ ﺗﻌﺪﻳﻞ ﻫﻮ‬
‫وﻓﻲ اﻟﺒﺪاﻳﺔ ﻗﺒﻞ وﺿﻊ ﺻﻮر اﻟﻜﻠﻤﺎت ﺳﻨﺴﺘﺨﺪم ﺻﻮرة ﻣﺆﻗﺘﺔ ﺗﺴﻤﻰ‬
‫ وﻓﻲ اﻟﻤﺜﺎل ﺗﻢ اﺳﺘﺨﺪام ﺻﻮرة اﻷﻳﻘﻮﻧﺔ ﻣﻦ‬placeholder ‫ﻓﻲ اﻟﺒﺮﻣﺠﺔ‬
mipmap ‫ﻣﻠﻒ اﻷﻳﻘﻮﻧﺎت‬
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
‫ﻓﻜﻤﺎ ﻫﻮ ﻣﻼﺣﻆ أﻧﻪ ﺗﻢ إدراج اﻟﺼﻮرة ﻓﻲ ﻣﺨﻄﻂ أب ﻣﻦ‬ xmlns:android="http://schemas.android.com/apk/res/android"
‫ أﻓﻘـﻲ وﺛــﻢ ﺗﻢ إدراج ﻣﺮﺑﻌﺎت اﻟﻨﺺ‬LinearLayout ‫ﻧــﻮع‬ xmlns:tools="http://schemas.android.com/tools"
‫ أﻳﻀﺎ ﻟﻜﻦ‬LinearLayout ‫اﻷﺛﻨﻴﻦ داﺧﻞ ﻣﺨﻄﻂ آﺧﺮ ﻣﻦ ﻧﻮع‬ android:layout_width="match_parent"
‫ﺑﺸﻜﻞ ﻋﻤﻮدة ﻓﺒﺎﻟﺘﺎﻟﻲ ﺣﺼﻠﻨﺎ ﻋﻠﻰ اﻟﺸﻜﻞ اﻟﻤﺒﻴﻦ أﻋﻼه‬ android:layout_height="wrap_content"
android:orientation="horizontal"
‫ إﺿﺎﻓﺔ اﻟﺼﻮر إﻟﻰ ﻣﺠﻠﺪ اﻟﺘﻄﺒﻴﻖ‬2 android:padding="16dp">
‫ﻋﻨﺪ ﻓﺘﺢ ﻣﺠﻠﺪ اﻟﺼﻮر ﻋﺪة ﻣﺠﻠﺪات‬
<ImageView
‫ﻛﻞ ﻣﻨﻬﺎ ﻓﻴﻪ ﻧﻔﺲ اﻟﺼﻮر ﻟﻜﻦ‬
android:id="@+id/image"
‫ﺑﺄﺣﺠﺎم ﻣﺨﺘﻠﻒ ﻳﺘﻢ اﺳﺘﺨﺪام‬
android:layout_width="wrap_content"
‫اﻟﺤﺠﻢ اﻟﻤﻨﺎﺳﺐ ﻟﻠﺠﻬﺎز اﻟﺬي ﻳﻌﻤﻞ‬ android:layout_height="wrap_content"
‫ ﻣﻦ ﺧﻼل ﻫﺬا اﻟﻤﻮﻗﻊ‬.‫ﻋﻠﻴﻪ اﻟﺘﻄﺒﻴﻖ‬ android:src="@mipmap/ic_launcher" />
‫ﻳﻤﻜﻦ أن ﺗﻌﺮف أﺣﺠﺎم اﻷﺟﻬﺰة‬
https://material.io/devices/ ‫اﻟﻤﺨﺘﻠﻔﺔ‬ <LinearLayout
‫اﻹﺳﻢ واﻟﺮﻗﻢ ﻓﻲ اﻟﺼﻮرة اﻟﺘﺎﻟﻴﺔ ﻳﻮﺿﺢ زﻳﺎدة وﺣﺪات‬ android:id="@+id/text_container"
android:layout_width="match_parent"
‫اﻟﺒﺴﻜﻞ ﻋﻠﻰ اﻟﺸﺎﺷﺎت ﺑﺰﻳﺎدة اﻟﻜﺜﺎﻓﺔ‬
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="16dp">

<TextView
android:id="@+id/miwok_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="lutti" />
‫وإذا ﻣﺎ ﻛﺎن ﻟﺪﻳﻨﺎ ﻧﺴﺨﺔ واﺣﺪة ﻣﻦ اﻟﺼﻮرة ﻓﻨﺤﺘﺎج أن ﺗﻜﻮن‬
‫ﻋﻠﻰ ﺣﺠﻢ ﻣﺘﺴﺎو ﺑﻐﺾ اﻟﻨﻈﺮ ﻋﻦ ﻋﺪد ﺑﻴﻜﺴﻼت اﻟﺠﻬﺎز‬ <TextView
android:id="@+id/default_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="one" />

</LinearLayout>
</LinearLayout>

38
‫ﺗﺎﺑــﻊ‬ ‫ﺧﻄﻮات اﻟﺘﻌﺪﻳﻞ ﻋﻠﻰ ﺗﻄﺒﻴﻖ ‪STEPS TO MODIFY AN APP‬‬

‫‪ 2‬إﺿﺎﻓﺔ اﻟﺼﻮر إﻟﻰ ﻣﺠﻠﺪ اﻟﺘﻄﺒﻴﻖ ‪ -‬ﺗﺎﺑﻊ‬


‫ﻛﻤﺎ ذﻛﺮﻧﺎ أﻧﻪ ﻟﻮ ﻛﺎن ﻟﺪﻳﻨﺎ ﺻﻮرة واﺣﺪ ﺑﺤﺠﻢ ﻛﺒﻴﺮ ﻓﻘﺪ ﻳﺤﺘﺎج اﻷﻧﺪرﻳﻮد إﻟﻲ ﺗﺼﻐﻴﺮﻫﺎ ﻓﻲ اﻷﺟﻬﺰة ذات اﻟﻜﺜﺎﻓﺔ‬
‫اﻟﻤﻨﺨﻔﻀﺔ وﻗﺪ ﻳﻨﺘﻬﻰ اﻷﻣﺮ إﻟﻰ ﺻﻮرة ﻣﺸﻮﻫﺔ أو ﺿﺒﺎﺑﻴﺔ وﻫﺬا ﻣﺎ ﻻ ﻧﺮﻳﺪه وﺑﺘﻮﻓﻴﺮ أﺣﺠﺎم ﻣﺨﺘﻠﻔﺔ ﻟﻠﺼﻮرة‬
‫ﺳﻨﺘﻔﺎدى ﻫﺬا اﻷﻣﺮ‬
‫ﻟﻤﻌﺮﻓﺔ ﺣﺠﻢ اﻟﺼﻮرة اﻷﺻﻠﻴﺔ اﻟﺘﻲ ﻳﺠﺐ أن ﻳﻘﺪﻣﻬﺎ ﻣﺼﻤﻢ اﻟﺼﻮر ﻓﻬﻨﺎك ﻧﺴﺒﺔ ﺗﺤﻮﻳﻞ ﻣﻦ ﻛﺜﺎﻓﺔ اﻟﺒﺴﻜﻞ إﻟﻰ‬
‫اﻟﺒﻜﺴﻞ ‪ db to px‬ﻛﻤﺎ ﻓﻲ اﻟﺼﻮرة‬

‫ﺣﺴﺐ ﻧﺴﺒﺔ اﻟﺘﺤﻮﻳﻞ ﻟﻮ ﻛﺎﻧﺖ ﻟﺪﻳﻨﺎ ﺻﻮرة ﺑﺤﺠﻢ ‪ 48‬ﺑﻴﻜﺴﻞ ﻓﻴﺠﺐ أن ﻳﻜﻮن ‪xxxhdpi‬‬ ‫=‬
‫ﺣﺠﻤﻬﺎ ﻟﻸﺟﻬﺰة اﻟﻌﺎﻟﻴﺔ اﻟﻜﺜﺎﻓﺔ ‪xxxhdpi = 4 x 48 ------> xxxhdpi = 192 px‬‬ ‫‪+‬‬
‫‪+‬‬
‫ﻳﺘﻢ إدراج اﻟﻤﺠﻠﺪات ﻟﻠﺼﻮر ﺟﻤﻴﻌﻬﺎ إﻟﻰ ﻣﺠﻠﺪات ‪ drawable‬ﻓﻲ ‪res‬‬ ‫‪+‬‬
‫ﻳﺮﺟﻰ اﻟﺮﺟﻮع ﻟﻠﺼﻔﺤﺔ ‪ 11‬ﻟﻤﻌﻠﻮﻣﺎت أﻛﺜﺮ ﺣﻮل إﺿﺎﻓﺔ اﻟﺼﻮر ﻓﻲ اﻷﻧﺪرﻳﻮد اﺳﺘﻮدﻳﻮ‬

‫ﺗﻌﺪﻳﻞ اﻟﺼﻨﻒ ‪Word.java‬‬ ‫‪3‬‬


‫اﻟﺼﻨﻒ ﺣﺎﻟﻴﺎ ﻳﺤﺘﻮي اﻟﺘﺮﺟﻤﺔ اﻹﻓﺘﺮاﺿﻴﺔ ‪ defaulTranslation‬واﻟﻜﻠﻤﺎت ﺑﻠﻐﺔ ‪Miwok‬‬
‫ﺳﻨﻘﻮم اﻵن ﺑﺈﺿﺎﻓﺔ اﻟﻜﻮد اﻟﻼزم ﻹﻇﻬﺎر اﻟﺼﻮرة اﻟﻤﻄﻠﻮﺑﺔ ﻟﻠﻜﻠﻤﺎت اﻟﻤﻌﺮوﺿﺔ‬
‫ﻧﻀﻴﻒ ﻫﺬا اﻟﻤﺘﻐﻴﺮ ﻟﻴﺨﺰن اﻟـ ‪ ID‬ﻟﻠﺼﻮرة اﻟﺘﻲ ﺳﻴﺘﻢ ﻋﺮﺿﻬﺎ‬ ‫;‪private int mImageResourceId = NO_IMAGE_PROVIDED‬‬
‫وأﺿﻔﻨﺎ اﻟﺜﺎﺑﺖ ﺣﺘﻰ ﻻ ﻳﻌﻄﻴﻨﺎ ﻣﺮﺟﻊ ﻟﺼﻮرة اﺑﺘﺪاءا وﺳﻨﺴﺘﺨﺪم‬ ‫;‪private static final int NO_IMAGE_PROVIDED = -1‬‬
‫ﻫﺬه اﻟﻘﻴﻤﺔ ﻟﺘﺤﺪﻳﺪ إذا ﻣﺎ ﻛﺎن ﻫﻨﺎك ﺻﻮرة أم ﻻ‬
‫ﻫﺬه اﻟﻄﺮﻳﻘﺔ ‪ Method‬ﻛﺬﻟﻚ ﺳﻨﺴﺘﺨﺪﻣﻬﺎ ﻹرﺟﺎع ‪ ID‬وﻋﺮض‬ ‫{ )(‪public int getImageResourceId‬‬
‫اﻟﺼﻮرة‬ ‫;‪return mImageResourceId‬‬
‫}‬
‫ﺑﻌﺪ ﺗﻌﺪﻳﻞ ﺻﻨﻒ ‪ Word‬واﺳﺘﺨﺪام اﻟﻜﻮﻧﺴﺘﺮاﻛﺘﻮر اﻟﺠﺪﻳﺪ ﻳﺠﺐ‬ ‫(‪words.add‬‬
‫ﻛﺬﻟﻚ ﺗﻐﻴﻴﺮ اﻟﻜﻮدات ﻟﻠﻘﻮاﺋﻢ اﻟﺘﻲ ﻳﺠﺐ أن ﻳﻜﻮن ﻓﻴﻬﺎ ﺻﻮر‬ ‫‪new Word("red", "we e i", R.drawable.color_red‬‬
‫;))‬
‫ﺑﻤﺎ أن ﻫﻨﺎك ﻗﻮاﺋﻢ ﻓﻲ اﻟﺘﻄﺒﻴﻖ ﻟﻦ‬ ‫{ )‪public Word(String defaultTrans, String miwokTrans‬‬
‫;‪mDefaultTranslation = defaultTrans‬‬
‫ﻳﻜﻮن ﻓﻴﻬﺎ ﺻﻮرة ﻓﻠﻦ ﻧﺴﺘﻄﻴﻊ‬ ‫;‪mMiwokTranslation = miwokTrans‬‬
‫اﺳﺘﺨـﺪام اﻟـ ‪ Constructor‬ﻧﻔﺴﻪ ﻟﻜﻞ‬ ‫}‬
‫اﻟﻘﻮاﺋﻢ وﻳﻼﺣﻆ أﻧﻪ ﻳﻤﻜﻨﻨﺎ اﺳﺘﺨﺪام‬
‫{ )‪public Word(String defaultTrans, String miwokTrans, int imageResourceId‬‬
‫أﻛﺜﺮ ﻣﻦ ﻛﻮﻧﺴﺘﺮاﻛﺘﻮر ﻓﻲ ﻧﻔﺲ اﻟﻮﻗﺖ‬ ‫;‪mDefaultTranslation = defaultTrans‬‬
‫;‪mMiwokTranslation = miwokTrans‬‬
‫;‪mImageResourceId = imageResourceId‬‬
‫}‬

‫‪39‬‬
‫ﺗﺎﺑــﻊ‬ ‫ﺧﻄﻮات اﻟﺘﻌﺪﻳﻞ ﻋﻠﻰ ﺗﻄﺒﻴﻖ ‪STEPS TO MODIFY AN APP‬‬
‫ﻫﺬه اﻟﻄﺮﻳﻘﺔ ‪Method‬ﻛﺬﻟﻚ ﺳﻨﺴﺘﺨﺪﻣﻬﺎ ﻟﻠﺘﺄﻛﺪ ﻣﺎ إذا ﻛﺎن ﻟﻠﻌﻨﺼﺮ‬ ‫{ )(‪public boolean hasImage‬‬
‫ﺻﻮرة ﻣﻀﺎﻓﺔ أم ﻻ وﻣﻌﻨﺎﻫﺎ إرﺟﺎع ﻗﻴﻤﺔ اﻟﻤﺘﻐﻴﺮ إذا ﻛﺎن ﻻ ﻳﺴﺎوي‬ ‫;‪return mImageResourceId != NO_IMAGE_PROVIDED‬‬
‫ﻗﻴﻤﺔ اﻟﺜﺎﺑﺖ وﻫﻲ ‪ -1‬أي أن ﻫﻨﺎك ﺻﻮرة ﻣﻀﺎﻓﺔ‬ ‫}‬

‫‪ 4‬ﺗﻌﺪﻳﻞ اﻟﺼﻨﻒ ‪WordAdapter.java‬‬


‫ﺳﻨﻘﻮم اﻵن ﺑﺘﻌﺪﻳﻞ اﻟﺼﻨﻒ ‪ WordAdapter‬واﻟﺬي اﺳﺘﺨﺪﻣﻨﺎه ﻟﻌﺮض اﻟﻌﻨﺎﺻﺮ ﻓﻲ اﻟﻘﺎﺋﻤﺔ ‪ ، ListView‬ﺳﻨﻀﻴﻒ إﻟﻴﻪ‬
‫اﻟﺘﺎﻟﻲ داﺧﻞ اﻟﻄﺮﻳﻘﺔ ‪ getView‬ﺑﺤﻴﺚ ﺗﻌﺮض اﻟﺼﻮرة ﻓﻘﻂ ﻋﻨﺎﺻﺮ اﻟﻜﻠﻤﺎت اﻟﻤﻄﻠﻮﺑﺔ ﻓﻘﻂ‬
‫ﺗﻌﺮﻳﻒ ﻛﺎﺋﻦ اﻟﺼﻮرة ورﺑﻄﻪ ﺑﻌﺮض اﻟﺼﻮرة ‪R.id.image‬‬ ‫;)‪ImageView imageView = (ImageView) listItemView.findViewById(R.id.image‬‬
‫{ ))(‪ if (currentWord.hasImage‬اﻟﺘﺄﻛﺪ ﻣﻦ وﺟﻮد ﺻﻮرة ﻓﻲ ﻋﻨﺼﺮ اﻟﻘﺎﺋﻤﺔ اﻟﺤﺎﻟﻲ‬
‫ّ إذا ﻛﺎن ﻫﻨﺎك ﺻﻮرة ﻗﻢ ﺑﻌﺮﺿﻬﺎ ﺣﺴﺐ اﻟﺮﻗﻢ اﻟﻤﻌﺮف ﻟﻠﻤﻮارد ‪// ID‬‬
‫;))(‪imageView.setImageResource(currentWord.getImageResourceId‬‬
‫ﻗﻢ ﺑﺈﻇﻬﺎر ﻋﻨﺼﺮ ﻋﺮض اﻟﺼﻮرة ﻟﻌﺮض اﻟﺼﻮرة اﻟﺤﺎﻟﻴﺔ ‪//‬‬
‫;)‪imageView.setVisibility(View.VISIBLE‬‬
‫}‬
‫{ ‪ else‬ﻳﻮﺟﺪ ﻓﺮق ﻫﻨﺎ ﻟﻮ ﻗﻠﺖ ‪ View.INVISIBLE‬ﻓﺈن اﻟﺼﻮرة‬
‫ﺑﺪﻻ ﻣﻦ ذﻟﻚ إذا ﻟﻢ ﺗﻮﺟﺪ ﺻﻮرة ﻗﻢ ﺑﺈﺧﻔﺎء ﻋﻨﺼﺮ ﻋﺮض اﻟﺼﻮرة ‪ //‬ﻟﻦ ﺗﻈﻬﺮ ﻟﻜﻦ ﻋﻨﺼﺮ اﻟﻌﺮض ﺳﻴﻜﻮن ﻣﻮﺟﻮدا وﺳﻴﺄﺧﺬ‬
‫;)‪ imageView.setVisibility(View.GONE‬ﺣﻴﺰا ﻓﻲ اﻟﺸﺎﺷﺔ وﻫﺬا ﻣﺎ ﻻ ﻧﺮﻳﺪه ﻓﻲ ﺣﺎﻟﺘﻨﺎ‬
‫}‬

‫ﻟﻜﻞ ﻗﺎﺋﻤﺔ ﻣﻦ ﻗﻮاﺋﻢ اﻟﻜﻠﻤﺎت ﻟﻮن ﺧﻠﻔﻴﺔ ﻣﺨﺘﻠﻔﺔ وﻟﺬﻟﻚ ﻗﻤﻨﺎ ﺑﺈﺿﺎﻓﺔ ﻛﻮدات اﻟﺘﺤﻜﻢ ﺑﺄﻟﻮان اﻟﺨﻠﻔﻴﺔ ﻓﻲ ‪ArrayAdapter‬‬
‫وﻟﻢ ﻧﻀﻌﻬﺎ ﻓﻲ اﻟﺼﻨﻒ ‪ Word.java‬وذﻟﻚ أﻧﻨﺎ ﻟﻦ ﻧﺤﺘﺎج إﻟﻰ ﺗﻐﻴﻴﺮ اﻟﻠﻮن ﻟﻜﻞ ﻋﻨﺼﺮ ﻓﻲ اﻟﻘﺎﺋﻤﺔ ﻧﻔﺴﻬﺎ ﺑﻞ ﻛﻞ ﻗﺎﺋﻤﺔ‬
‫ﻛﻠﻤﺎت ﻟﻬﺎ ﻟﻮن واﺣﺪ ﻓﺎﻷﻓﻀﻞ ﻫﻮ اﻟﺘﻌﺪﻳﻞ ﻋﻠﻰ ‪WordAdapter‬‬
‫;‪ private int mColorResourceId‬أوﻻ ﻧﻌﺮف ﻣﺘﻐﻴﺮ ﻋﺎم داﺧﻞ اﻷدﺑﺘﻮر ﻟﺤﻔﻆ رﻗﻢ‬
‫ﻣﻮرد اﻷﻟﻮان‬
‫{ )‪ public WordAdapter(Context context, ArrayList<Word> words, int colorResourceId‬ﻳﺴﻤﻰ ﻫﺬا ‪ Constructor‬وﻳﺴﺘﺨﺪم ﻟﺮﺑﻂ‬
‫اﻟﻤﺘﻐﻴﺮات اﻟﺪاﺧﻠﻴﺔ ﺑﺎﻟﻤﺘﻐﻴﺮات اﻟﺘﻲ ﺗﺄﺗﻲ ﻣﻦ‬ ‫;)‪super(context, 0, words‬‬
‫;‪mColorResourceId = colorResourceId‬‬
‫ﺧﺎرج اﻟﺼﻨﻒ ﻋﺒﺮ اﻟـ ‪Constructor‬‬
‫ﻣﺘﻐﻴﺮ داﺧﻠﻲ وﺣﺮف اﻟـ ‪ m‬ﻳﻌﻨﻲ ‪member‬‬ ‫}‬

‫;)‪ View textContainer = listItemView.findViewById(R.id.text_container‬ﺗﻌﺮﻳﻒ اﻟﻤﺨﻄﻂ اﻟﺬي ﻳﺤﻤﻞ ﻋﻨﺎﺻﺮ اﻟﻮاﺟﻬﺔ‬


‫اﻟﺘﻲ ﺳﺘﻈﻬﺮ ﻓﻲ اﻟﻘﺎﺋﻤﺔ ‪ListView‬‬
‫;)‪ int color = ContextCompat.getColor(getContext(), mColorResourceId‬إﻳﺠﺎداﻟﻠﻮناﻟﺬيﺣﺪدهاﻟﻤﺘﻐﻴﺮ ‪mColorResourceId‬‬
‫;)‪ textContainer.setBackgroundColor(color‬ﺗﻐﻴﻴﺮ ﻟﻮن اﻟﺨﻠﻔﻴﺔ ﻟﻠﻤﺨﻄﻂ اﻟﻤﺤﺘﻮى ﻟﻠﻨﺺ‬

‫ﺑﻌﺪ ﻫﺬه اﻟﺘﻌﺪﻳﻼت ﻧﻌﻮد ﻟﻜﻮدات اﻟﻨﺸﺎط وﻧﻐﻴﺮ ﺗﻌﺮﻳﻒ اﻷدﺑﺘﻮر ﺑﺰﻳﺎدة إﺿﺎﻓﺔ اﻟﻠﻮن اﻟﻤﻄﻠﻮب ﻟﻠﺨﻠﻔﻴﺔ واﻟﺬي ﺳﻴﻜﻮن‬
‫;)‪WordAdapter adapter = new WordAdapter(this, words, R.color.category_numbers‬‬ ‫ﻣﺮﺟﻊ رﻗﻤﻪ اﻟﻤﻌﺮف ﻣﻦ ﻣﻮارد اﻷﻟﻮان‬

‫‪40‬‬
‫ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ ‪MEDIAPLAYER‬‬
‫اﻟﺼﻨﻒ ‪ MediaPlayer‬ﻳﻌﺘﺒﺮ ﺻﻨﻒ ﻣﺮﻛﺐ ﻷن ﻳﻤﻜﻨﻪ ﺗﺸﻐﻴﻞ اﻟﺼﻮﺗﻴﺎت واﻟﻤﺮﺋﻴﺎت ﻓﻲ ﺗﻄﺒﻴﻘﺎت اﻷﻧﺪرﻳﻮد وﻫﺬه‬
‫اﻟﺼﻮﺗﻴﺎت أو اﻟﻤﺮﺋﻴﺎت ﻳﻤﻜﻦ ﺿﻤﻴﻨﻬﺎ ﻓﻲ ﻣﻠﻒ اﻟﻤﻮارد أو ﺗﺸﻐﻴﻠﻬﺎ ﻋﻦ ﻃﺮﻳﻖ اﻹﻧﺘﺮﻧﺖ‬
‫ﻗﺎﺋﻤﺔ ﺑﺒﻌﺾ أﻧﻮاع اﻟﺼﻮﺗﻴﺎت واﻟﻤﺮﺋﻴﺎت اﻟﺘﻲ ﻳﺸﻐﻠﻬﺎ اﻷﻧﺪرﻳﻮد‬
‫اﻟﺼــــــــﻮر‬ ‫اﻟﻔﻴﺪﻳــﻮﻫﺎت‬ ‫اﻟﺼﻮﺗﻴـــﺎت‬
‫‪BMP‬‬ ‫‪GIF JPEG PNG‬‬ ‫اﻟﻔﻴﺪﻳﻮﻫﺎت ‪MP4 MKV 3GPP WEBM‬‬ ‫‪MP3 WAV OGG MID‬‬

‫ﻟﻤﻌﻠﻮﻣﺎت أﻛﺜﺮ ﻋﻦ أﻧﻮع ﻣﻠﻔﺎت اﻟﻮﺳﺎﺋﻂ اﻟﻤﺪﻋﻮﻣﺔ ﻳﺮﺟﻰ زﻳﺎرة ﻫﺬا اﻟﻤﻮﻗﻊ‬
‫‪https://developer.android.com/guide/topics/media/media-formats.html‬‬
‫ﻳﺘﻢ اﻟﺘﺤﻜﻢ ﺑﻤﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ ﻋﻦ ﻃﺮﻳﻖ ﺗﺴﻠﺴﻞ اﻟﺤﺎﻻت ‪ State Machine‬وﻫﺬا ﻳﻌﻨﻲ أن ﻫﻨﺎك ﺣﺎﻻت ﻣﺨﺘﻠﻔﺔ ﻳﺘﻢ‬
‫اﻟﺘﻨﻘﻞ ﺑﻴﻨﻬﺎ‪ ،‬وﺑﺎﻟﺘﺎﻟﻲ ﻳﻤﻜﻨﻨﺎ رﺳﻢ ﻣﺨﻄﻂ ﻳﻌﺮف ﺑﺎﺳﻢ اﻟﺮﺳﻢ اﻟﺒﻴﺎﻧﻲ ﻟﺘﺴﻠﺴﻞ اﻟﺤﺎﻻت ‪State Machine Diagram‬‬
‫ﻟﻠﻤﺴﺎﻋﺪة ﻓﻲ ﺗﺼﻮر اﻟﺤﺎﻻت اﻟﻤﺨﺘﻠﻔﺔ ﻋﻨﺪ ﺗﺸﻐﻴﻞ ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ‬
‫‪Paused‬‬ ‫‪Started‬‬ ‫‪Prepared‬‬ ‫‪Idle‬‬
‫اﻹﻳﻘﺎف اﻟﻤﺆﻗﺖ‬ ‫ﺣﺎﻟﺔ اﻟﺘﺸﻐﻴﻞ‬ ‫ﺣﺎﻟﺔ اﻟﺠﺎﻫﺰﻳﺔ‬ ‫ﺣﺎﻟﺔ اﻟﺨﻤﻮل‬
‫إﻳﻘﺎف ﻣﺆﻗﺖ‬ ‫ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ‬ ‫ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ‬ ‫ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ‬
‫ﻟﻤﻠﻒ اﻟﻮﺳﺎﺋﻂ‬ ‫ﻣﻠﻒ‬ ‫ﻳﺸﻐﻞ‬ ‫ﻳﺴﺘﻌﺪ ﻟﺘﺸﻐﻴﻞ‬ ‫ﻣﻮﺟﻮد ﻟﻜﻦ ﻻ‬
‫اﻟﺬي ﺗﻢ ﺗﺸﻐﻴﻠﻪ‬ ‫وﺳﺎﺋﻂ‬ ‫ﻣﻠﻒ وﺳﺎﺋﻂ‬ ‫ﻳﺼﺪر ﺻﻮﺗﺎ‬

‫‪Stopped‬‬
‫اﻹﻳﻘﺎف اﻟﻜﻠﻲ‬
‫ﻛﻠﻲ‬ ‫إﻳﻘﺎف‬
‫ﻟﻤﻠﻒ اﻟﻮﺳﺎﺋﻂ‬
‫اﻟﺬي ﺗﻢ ﺗﺸﻐﻴﻠﻪ‬
‫ﻟﻤﻌﻠﻮﻣﺎت أﻛﺜﺮ ﻋﻦ ﺣﺎﻻت أﺧﺮى ﻟﻤﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ ﻳﺮﺟﻰ زﻳﺎرة ﻫﺬا اﻟﻤﻮﻗﻊ‬
‫‪https://developer.android.com/reference/android/media/MediaPlayer.html‬‬
‫ﻳﺘﻢ ﺗﻌﺮﻳﻒ ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ ﺑﺈﺳﺘﺨﺪام ﻃﺮﻳﻘﺔ اﻟﻤﺼﻨﻊ ‪ Factory Method‬ﻓﻲ ﺗﻌﺮﻳﻒ اﻟﻜﺎﺋﻨﺎت‬
‫ﺧﻄﻮات إﺿﺎﻓﺔ ﻣﺸﻐﻞ اﻟﺼﻮﺗﻴﺎت إﻟﻰ اﻟﺘﻄﺒﻴﻖ‬
‫‪ 1‬إﺿﺎﻓﺔ ﻣﺴﻤﺘﻊ اﻷﺣﺪاث ﻟﻌﻨﺎﺻﺮ ﻗﺎﺋﻤﺔ ‪ listView‬ﺑﺈﺳﺘﺨﺪام )(‪setOnItemClickListener‬‬
‫ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﺮ ﺟﺪﻳﺪ ﻟﻜﺎﺋﻦ ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ‪//‬‬
‫;‪private MediaPlayer mMediaPlayer‬‬
‫{ )(‪listView.setOnItemClickListener(new AdapterView.OnItemClickListener‬‬
‫‪@Override‬‬
‫{ )‪public void onItemClick(AdapterView<?> adapterView, View view, int position, long l‬‬
‫ﺗﺤﺪﻳﺪ ﻣﻜﺎن ورﻗﻢ ﻣﻌﺮف اﻟﻌﻨﺼﺮ اﻟﺬي ﺗﻢ اﻟﻀﻐﻂ ﻋﻠﻴﻪ ﻓﻲ اﻟﻘﺎﺋﻤﺔ ‪//‬‬
‫;)‪Word word = words.get(position‬‬
‫إﻋﻄﺎء ﻗﻴﻤﺔ ﻟﻤﺘﻐﻴﺮ ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ وإﻋﻄﺎءه أﻣﺮ ﺑﺘﺠﻬﻴﺰ ﻣﻠﻒ اﻟﻤﻮارد اﻟﺼﻮﺗﻲ‪//‬‬
‫;))(‪mMediaPlayer = MediaPlayer.create(NumbersActivity.this, word.getAudioResourceId‬‬
‫ﺗﺸﻐﻴﻞ ﻣﻠﻒ اﻟﻤﻮارد اﻟﺼﻮﺗﻲ‪//‬‬
‫;)(‪mMediaPlayer.start‬‬ ‫ﻫﺬا ﻣﺮﺟﻊ ﻟﻤﻠﻒ اﻟﻮﺳﺎﺋﻂ‬
‫;)} }‬ ‫ﻫﺬا ﻣﺮﺟﻊ ﻟﻠﻨﺸﺎط اﻟﺬي ﺳﻴﻌﻤﻞ ﻋﻠﻴﻪ ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ‬

‫‪41‬‬
‫ﺗﺎﺑــﻊ‬ MEDIAPLAYER ‫ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ‬

res>raw ‫ إﺿﺎﻓﺔ ﻣﻠﻔﺎت اﻟﻮﺳﺎﺋﻂ إﻟﻰ اﻟﻤﻠﺠﻠﺪ‬2


‫ وﻧﻀﻊ داﺧﻠﻪ ﺟﻤﻴﻊ‬raw ‫ﻳﺘﻢ ﻋﻤﻞ ﻣﻠﻒ داﺧﻞ ﻣﺠﻠﺪ اﻟﻤﻮارد ﻧﺴﻤﻴﻪ‬
‫ وﺗﻨﻄﺒﻖ ﻗﻮاﻋﺪ ﺗﺴﻤﻴﺔ اﻟﻮﺳﺎﺋﻂ ﺑﻨﻔﺲ‬،‫اﻟﻤﻮارد ﻣﻦ ﻧﻮع وﺳﺎﺋﻂ‬
‫ﻃﺮﻳﻘﺔ ﺗﺴﻤﻴﺔ اﻟﺼﻮر‬

Word.java ‫اﻟﺘﻌﺪﻳﻞ ﻓﻲ اﻟﺼﻨﻒ‬ 3


‫إﺿﺎﻓﺔ ﻣﺘﻐﻴﺮ ﻟﺘﺤﺪﻳﺪ رﻗﻢ ﻣﻌﺮف‬ private int mAudioResourceId;
‫ﻣﻮارد اﻟﺼﻮت‬
‫ وإﺿﺎﻓﺔ‬Constructor ‫اﻟﺘﻌﺪﻳﻞ ﻋﻠﻰ اﻟـ‬ public Word(String defaultTranslation, String miwokTranslation, int audioResourceId) {
mAudioResourceId ‫اﻟﻤﺘﻐﻴﺮ‬ mDefaultTranslation = defaultTranslation;
mMiwokTranslation = miwokTranslation;
mAudioResourceId = audioResourceId;
}
‫اﻟﻄﺮﻳﻘﺔ اﻟﻤﺴﺘﺨﺪم ﻹرﺟﺎع اﻟﺮﻗﻢ‬ public int getAudioResourceId() {
‫اﻟﻤﻌﺮف ﻟﻤﻮارد اﻟﻮﺳﺎﺋﻂ اﻟﻤﻄﻠﻮﺑﺔ‬ return mAudioResourceId;
}

‫ وﺑﻬﺬه اﻟﻄﺮﻳﻘﺔ ﻳﻤﻜﻦ اﻟﺮﺟﻮع إﻟﻰ ﻗﺎﺋﻤﺔ اﻟﻤﺼﻔﻮﻓﺔ‬ArrayList ‫ ﻗﺒﻞ ﺗﻌﺮﻳﻒ اﻟﻤﺼﻔﻮﻓﺔ‬final ‫ﻳﺠﺐ أن ﻧﻀﻊ اﻟﻜﻠﻤﺔ‬
final ArrayList<Word> words = new ArrayList<Word>(); onItemClick ‫ﺿﻤﻦ وﻇﻴﻔﺔ‬
words.add(new Word("father", "әpә", R.drawable.family_father, R.raw.family_father));
words.add(new Word("mother", "ә a", R.drawable.family_mother, R.raw.family_mother));
words.add(new Word("daughter", "tune", R.drawable.family_daughter, R.raw.family_daughter));

‫ ﻓﻲ اﻟﺼﻨﻒ اﻟﻮاﺣﺪ ﻣﺎدام أن ﻛﻞ ﻣﻨﻬﻤﺎ ﻳﺤﺘﻮي ﻋﻮام إدﺧﺎل ﻣﺨﺘﻠﻔﺔ ﻋﻦ اﻵﺧﺮ‬Constructor‫ﻳﻤﻜﻦ اﺳﺘﺨﺪام أﻛﺜﺮ ﻣﻦ‬

public Word(String defaultTranslation, String miwokTranslation, int audioResourceId) {}


public Word(String defaultTranslation, String miwokTranslation) {}

toString() ‫اﻷﺳﻠــﻮب‬
‫ ﻳﺘﻤﺜﻞ‬toString() ‫أﺳﻬﻞ وﺳﻴﻠﺔ ﻟﻄﺒﺎﻋﺔ ﻣﺤﺘﻮﻳﺎت ﻛﺎﺋﻦ ﺟﺎﻓﺎ ﻫﻲ ﺗﻮﻓﻴﺮ ﻃﺮﻳﻘﺔ ﺗﻨﻔﻴﺬ أﺳﻠﻮب‬
‫ ﻋﺎدة ﻷﻏﺮاض ﺗﺼﺤﻴﺢ اﻷﺧﻄﺎء‬،‫اﻟﻐﺮض ﻣﻦ ﻫﺬا اﻷﺳﻠﻮب ﻓﻲ ﻋﺮض اﻟﻜﺎﺋﻦ ﺑﺎﻟﻜﺎﻣﻞ ﻛﺴﻠﺴﻠﺔ‬
‫اﺿﻐﻂ ﻋﻠﻰ اﻟﺰر‬ 1 ‫ﺿﻊ اﻟﻤﺆﺷﺮ ﻓﻲ ﻣﺴﺎﺣﺔ ﻓﺎرﻏﺔ ﻓﻲ اﻟﻤﻠﻒ ﺧﺎرج‬ 1
ALT + Insert Methods ‫ﺣﺪود اﻟﻄﺮق‬
CMD + N

42
‫اﻹﺳﺘﺪﻋﺎءات اﻟﻐﻴﺮ ﻣﺘﺰاﻣﻨﺔ ‪ASYNC CALLBACKS‬‬
‫ﻛﻞ اﻹﺳﺘﺪﻋﺎءات ‪ CallBacks‬اﻟﺘﻲ ﺗﻢ اﺳﺘﺨﺪاﻣﻬﺎ ﻛﺎﻧﺖ ﻣﻦ ﻧﻮع ﻣﺘﺰاﻣﻦ أي ﺗﻢ ﺗﻄﺒﻴﻖ اﻟﻜﻮد واﺣﺪا ﺗﻠﻮ اﻵﺧﺮ دون‬
‫اﻧﺘﻈﺎر وﻋﻠﻴﻚ اﻧﺘﻈﺎر اﻻﻧﺘﻬﺎء ﻣﻦ ﺗﻨﻔﻴﺬ ﻛﻞ ﺳﻄﺮ ﻗﺒﻞ اﻟﺬﻫﺎب إﻟﻰ اﻟﺴﻄﺮ اﻟﺘﺎﻟﻲ‪ .‬ﻟﻜﻦ اﻻﺳﺘﺪﻋﺎء اﻟﻐﻴﺮ ﻣﺘﺰاﻣﻦ ﻳﺘﻢ‬
‫اﺳﺘﺨﺪاﻣﻪ ﻓﻘﻂ ﻋﻨﺪﻣﺎ ﻳﺘﻢ ﻃﻠﺒﻪ وﻳﻤﻜﻦ ﻟﻠﻤﺴﺘﺨﺪم اﻟﻌﻤﻞ ﻋﻠﻰ اﻟﺘﻄﺒﻴﻖ ﺑﻴﻨﻤﺎ ﻳﺘﻢ ﻫﺬا اﻹﺳﺘﺪﻋﺎء ﻓﻲ اﻟﺨﻠﻔﻴﺔ‬
‫ﻓﻤﺜﺎل ذﻟﻚ ﻓﻲ ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ ﺳﻨﺴﺘﺨﺪم اﺳﺘﺪﻋﺎء ﻏﻴﺮ ﻣﺘﺰاﻣﻦ ﻟﻺﺧﺒﺎر ﺑﺈﻧﺘﻬﺎء ﺗﺸﻐﻴﻞ اﻟﻤﻠﻒ اﻟﺼﻮﺗﻲ وﻟﻜﻦ‬
‫ﺳﻴﻜﻮن ﻫﺬا اﻹﺧﺒﺎر ﺑﻌﺪ ﺗﺸﻐﻴﻞ ﻣﻠﻒ اﻟﻮﺳﺎﺋﻂ وﻟﺬﻟﻚ ﻧﺴﺘﺨﺪم )(‪setOnCompletionListener‬‬
‫{ )(‪private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener‬‬
‫‪@Override‬‬
‫ﻋﻨﺪ اﻧﺘﻬﺎء اﻟﻤﻠﻒ اﻟﺼﻮﺗﻲ‬
‫{ )‪public void onCompletion(MediaPlayer mediaPlayer‬‬
‫ﺗﻠﻘﺎﺋﻴﺎ ﺳﻴﻨﺘﻘﻞ اﻟﻜﻮد إﻟﻰ ﻃﺮﻳﻘﺔ‬
‫;)(‪releaseMediaPlayer‬‬
‫ﺣﺬف ﻣﻮارد ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ‬
‫}‬
‫ﺑﺸﻜـــﻞ ﻏﻴــﺮ ﻣﺘﺰاﻣــﻦ ‪ASYNC‬‬
‫;}‬
‫ﻋﻨﺪ ﺗﺸﻐﻴﻞ ﻣﻠﻔﺎت اﻟﻮﺳﺎﺋﻂ ﻣﻦ اﻟﻤﻌﺮوف أن ﻫﺬا ﻳﺴﺘﻬﻠﻚ اﻟﻜﺜﻴﺮ ﻣﻦ اﻟﺬاﻛﺮة ﻓﻜﻴﻒ ﻧﺤﺪد أﻧﻨﺎ ﻻ ﻧﺤﺘﺎج ﻣﻮارد‬
‫ﻣﻌﻴﻨﺔ وﻛﻴﻒ ﻧﻘﻮم ﺑﺈﻓﺮاﻏﻬﺎ‬
‫ﻧﺴﺘﺨﺪم اﻟﻄﺮﻳﻘﺔ ;)(‪ release‬ﻹﺧﻼء ﻣﻮارد ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ‬
‫ﺳﻨﺴﺘﺨﺪم ﻫﺬه اﻟﻄﺮﻳﻘﺔ ﻹﻓﺮاغ ﻣﻮارد ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ ‪//‬‬
‫{ )(‪private void releaseMediaPlayer‬‬
‫أوﻻ ﻧﺘﺄﻛﺪ ﻣﻦ وﺟﻮد ﻛﺎﺋﻦ ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ وأﻧﻪ ﻻ ﻳﻘﻮم ﺑﺘﺸﻐﻴﻞ ﻣﻠﻒ وﺳﺎﺋﻂ ﺣﺎﻟﻴﺎ ‪//‬‬
‫{ )‪if (mMediaPlayer != null‬‬
‫ﺑﻐﺾ اﻟﻨﻈﺮ ﻋﻦ ﺣﺎﻟﺔ ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ ﺳﻴﺘﻢ إﻓﺮاغ ﻣﻮارده ‪//‬‬
‫;)(‪mMediaPlayer.release‬‬
‫إﻋﺎﻃﺎء اﻟﻘﻴﻤﺔ )ﻓﺎرغ( ﻟﻤﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ ﻟﺘﺤﺪﻳﺪ أﻧﻪ ﻏﻴﺮ ﺟﺎﻫﺰ ﻟﺘﺸﻐﻴﻞ وﺳﺎﺋﻂ ﺣﺎﻟﻴﺎ ‪//‬‬
‫;‪mMediaPlayer = null‬‬
‫}‬
‫}‬
‫ﻳﺠﺐ إدراج ﻣﺴﺘﻤﻊ اﻷﺣﺪاث إﻟﻤﺴﺆول ﻋﻦ إﻓﺎرغ ﻣﻮارد ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ‬
‫;)‪mMediaPlayer.setOnCompletionListener(mCompletionListener‬‬

‫أﻫﻢ اﻷﻣﻮر اﻟﺘﻲ ﻳﺠﺐ أن ﻳﻌﻤﻠﻬﺎ اﻟﻤﺒﺮﻣﺞ ﻫﻮ اﻟﺘﺨﻠﺺ ﻣﻦ اﻟﻤﻮارد اﻟﺘﻲ ﺗﺸﻐﻞ اﻟﺬاﻛﺮة ﻋﻨﺪﻣﺎ ﻟﻢ ﺗﻌﺪ ﺣﺎﺟﺔ إﻟﻴﻬﺎ‬
‫ﻓﺘﺴﺘﻄﻴﻊ ﺗﻄﺒﻴﻘﺎت اﻟﺠﻬﺎز اﻷﺧﺮى اﺳﺘﺨﺪام ﻫﺬه اﻟﺬاﻛﺮة‬

‫‪43‬‬
‫دورة ﺣﻴﺎة اﻟﻨﺸﺎط ‪ACTIVITY CYCLE‬‬
‫ﻓﻲ أﻏﻠﺐ اﻷوﻗﺎت ﺳﻴﻜﻮن اﻟﻤﺴﺘﺨﺪم داﺧﻞ ﺗﻄﺒﻴﻘﻚ ﻓﻲ ﻧﺸﺎط ‪ Activity‬ﻣﻌﻴﻦ‪ ،‬ﻟﻜﻦ ﻣﺎذا ﻟﻮ ﻗﺮر اﻟﻤﺴﺘﺨﺪم اﻟﺨﺮوج‬
‫ﻣﻦ اﻟﺘﻄﺒﻴﻖ واﺳﺘﺨﺪام ﺗﻄﺒﻴﻖ آﺧﺮ أو أﺗﺘﻪ ﻣﻜﺎﻟﻤﺔ‪ ،‬ﻫﻨﺎ ﻗﺪ ﻳﺘﻮﺟﺐ ﻋﻠﻴﻨﺎ اﻧﻬﺎء اﻟﺘﻄﺒﻴﻖ وإﻓﺮاغ ﻣﻮارد أو اﻟﺬاﻛﺮة‪ ،‬أو‬
‫ﺳﻴﻔﻀﻞ ﺣﻔﻆ ﺣﺎﻟﺔ اﻟﺘﻄﺒﻴﻖ اﻟﺘﻲ ﺗﺮﻛﻬﺎ اﻟﻤﺴﺘﺨﺪم ﻟﻠﻌﻮدة إﻟﻴﻬﺎ وإﺗﻤﺎم ﻋﻤﻠﻪ‪ ،‬ﻣﺜﻞ ﻛﺘﺎب رﺳﺎل ﺑﺮﻳﺪ إﻟﻜﺘﺮوﻧﻲ‪ ،‬ﻓﺈن‬
‫اﻟﻤﺴﺘﺨﺪم ﻟﻮ ﺧﺮج ﻣﻦ اﻟﺘﻄﺒﻴﻖ ﻟﺴﺒﺐ ﻣﺎ ورﺟﻊ إﻟﻴﻪ وﻟﻢ ﻳﺠﺪ ﻣﺎ ﻛﺘﺒﻪ أﻧﻪ ﻗﺪ ﺣﻔﻆ ﻛﻤﺴﻮدة ﺳﻴﻜﻮن أﻣﺮا ﺑﺎﻟﻨﺴﺒﺔ ﻟﻪ‬
‫ﻟﺘﻮﻓﻴﺮ ﻫﻴﻜﻞ ﻟﺠﻤﻴﻊ اﻟﺤﺎﻻت ﻋﺪم اﻛﺘﻤﺎل اﻟﻌﻤﻞ ﻋﻠﻰ اﻟﺘﻄﺒﻴﻖ‪ ،‬أﻧﺪرﻳﻮد ﻟﺪﻳﻪ دورة ﺣﻴﺎة ‪ Life Cycle‬ﻳﻤﻜﻦ ﻣﻦ ﺧﻼﻟﻬﺎ‬
‫ﺗﺘﺒﻊ أﺣﺪاث ﺟﻤﻴﻊ اﻷﻧﺸﻄﺔ ﻓﻲ اﻟﺘﻄﺒﻴﻘﺎت‬
‫إذا ﻋﺎد اﻟﻤﺴﺘﺨﺪم إﻟﻰ اﻟﻨﺸﺎط واﻟﻌﻤﻞ ﻋﻠﻴﻪ ﻣﺮة أﺧﺮى‬

‫‪Destroyed‬‬ ‫‪Stopped‬‬ ‫‪Paused‬‬ ‫‪Resumed‬‬ ‫‪Started‬‬ ‫‪Created‬‬


‫اﻹﺗﻼف ﻟﻠﻨﺸﺎط‬ ‫اﻹﻳﻘﺎف ﻟﻠﻨﺸﺎط‬ ‫اﻹﻳﻘﺎف اﻟﻤﺆﻗﺖ‬ ‫إﺳﺘﺌﻨﺎف اﻟﻨﺸﺎط‬ ‫ﺑﺪء اﻟﻨﺸــﺎط‬ ‫إﻧﺸﺎء اﻟﻨﺸﺎط‬

‫ﻋﻨﺪ اﻏﻼق اﻟﻨﺸﺎط‬ ‫ﻋﻨﺪ اﻧﺘﻘﺎل اﻟﻤﺴﺘﺨﺪم إﻟﻰ ﻧﺸﺎط أو ﺗﻄﺒﻴﻖ‬ ‫ﻫﻨﺎ ﻳﺼﺒﺢ اﻟﻨﺸﺎط ﻫﻨﺎ ﻳﻜﻮن اﻟﻨﺸﺎط ﻓﻌﺎل‬
‫أو ﺣﺪد اﻟﻨﻈﺎم أن‬ ‫ﻣﺨﺘﻠﻒ‬ ‫وﺑﺈﻣﻜﺎن اﻟﻤﺴﺘﺨﺪم‬ ‫ﻣﺮﺋﻲ ﻟﻠﻤﺴﺘﺨﺪم‬
‫اﻟﻤﺴﺘﺨﺪم ﻻ ﻳﺤﺘﺎج‬ ‫اﻟﺘﻔﺎﻋﻞ ﻣﻌﻪ‬
‫اﻟﻨﺸﺎط‬
‫)(‪OnDestroy‬‬ ‫)(‪OnStop‬‬ ‫)(‪OnPause‬‬ ‫)(‪OnResume‬‬ ‫)(‪OnStart‬‬ ‫)(‪OnCreate‬‬

‫ﻟﻤﻌﻠﻮﻣﺎت أﻛﺜﺮ ﺣﻮل دورة ﺣﻴﺎة اﻟﻨﺸﺎط ﻳﻤﻜﻨﻚ زﻳﺎرة ﻫﺬا اﻟﻤﻮﻗﻊ‬
‫‪https://developer.android.com/reference/android/app/Activity.html‬‬
‫ﻧﻤﻮذج ﻧﺸﺎط ﻳﻮﺿﺢ دورة ﺣﻴﺎة اﻟﻨﺸﺎط‬

‫‪@Override‬‬ ‫‪@Override‬‬
‫{ )‪protected void onCreate(Bundle savedInstanceState‬‬ ‫{ )(‪protected void onPause‬‬
‫;)‪super.onCreate(savedInstanceState‬‬ ‫;)(‪super.onPause‬‬
‫;)‪setContentView(R.layout.activity_main‬‬ ‫;)"‪Log.v("MainActivity", "onPause‬‬
‫;)"‪Log.v("MainActivity", "onCreate‬‬ ‫}‬
‫}‬

‫‪@Override‬‬ ‫‪@Override‬‬
‫{ )(‪protected void onStart‬‬ ‫{ )(‪protected void onStop‬‬
‫;)(‪super.onStart‬‬ ‫;)(‪super.onStop‬‬
‫;)"‪Log.v("MainActivity", "onStart‬‬ ‫;)"‪Log.v("MainActivity", "onStop‬‬
‫}‬ ‫}‬

‫‪@Override‬‬ ‫‪@Override‬‬
‫{ )(‪protected void onResume‬‬ ‫{ )(‪protected void onDestroy‬‬
‫;)(‪super.onResume‬‬ ‫;)(‪super.onDestroy‬‬
‫;)"‪Log.v("MainActivity", "onResume‬‬ ‫;)"‪Log.v("MainActivity", "onDestroy‬‬
‫}‬ ‫}‬
‫ﻋﻨﺪ ﺗﺠﺮﺑﺔ ﻫﺬا اﻟﻤﺜﺎل ﻓﻲ اﻷﻧﺪرﻳﻮد اﺳﺘﻮدﻳﻮ ﺳﻴﺘﻢ ﻃﺒﺎﻋﺔ ﺳﻄﺮ ﻋﻨﺪ ﻛﻞ ﺣﻠﻘﺔ ﻓﻲ دورة ﺣﻴﺎة اﻟﻨﺸﺎط وﺳﺘﻈﻬﺮ‬
‫اﻟﻜﺘﺎﺑﺔ ﻓﻲ ﺷﺎﺷﺔ اﻟﺮﺳﺎﺋﻞ ﻓﻲ اﻷﺳﻔﻞ‪ ،‬ﺟﺮب اﻏﻼق اﻟﺘﻄﺒﻴﻖ أو وﺿﻌﻪ ﻓﻲ ﺷﺎﺷﺔ اﻟﺘﻄﺒﻴﻘﺎت اﻟﻤﺨﻔﻴﺔ واﻟﻌﻮدة إﻟﻴﻪ‬

‫‪44‬‬
‫ﺗﺎﺑــﻊ‬ ‫دورة ﺣﻴﺎة اﻟﻨﺸﺎط ‪ACTIVITY CYCLE‬‬
‫ﻟﻠﺤﺼﻮل ﻋﻠﻰ اﻟﻘﺎﺋﻤﺔ اﻟﻜﺎﻣﻠﺔ ﻟﻠﻄﺮق اﻟﺘﻲ‬
‫ﻳﻤﻜﻦ اﺳﺘﺨﺪاﻣﻬﺎ ﻟﺪورة ﺣﻴﺎة اﻟﻨﺸﺎط ﻧﻀﻐﻂ‬
‫‪Code>Override Methods‬‬ ‫ﻣﻦ اﻟﻘﺎﺋﻤﺔ‬
‫إذا ﻛﻨﺎ ﻧﺴﺘﺨﺪم ﻣﺸﻐﻞ وﺳﺎﺋﻂ ‪ MediaPlayer‬وﻗﺎم‬
‫اﻟﻤﺴﺘﺨﺪم ﺑﺘﺮك اﻟﻨﺸﺎط ﻓﻴﺠﺐ ﺣﺬف ﻣﻮارد‬
‫‪@Override‬‬
‫ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ ‪ release‬ﺧﻼل )(‪ OnStop‬ﻷﻧﻬﺎ‬
‫{ )(‪protected void onStop‬‬
‫اﻟﻄﺮﻳﻘﺔ اﻟﺘﻲ ﺳﺘﻜﻮن ﻣﻔﻌﻠﺔ ﺣﺎل ﺗﺮﻛﻨﺎ اﻟﺘﻄﺒﻴﻖ‬
‫;)(‪super.onStop‬‬
‫واﻟﺼﻮت ﺑﺬﻟﻚ ﺳﻴﺘﻮﻗﻒ‪ ،‬وإذا ﻟﻢ ﻧﻘﻢ ﺑﻬﺬه‬
‫;)(‪releaseMediaPlayer‬‬
‫اﻟﺨﻄﻮة ﻓﺈن اﻟﻮﺳﺎﺋﻂ ﺳﺘﻈﻞ ﺗﻌﻤﻞ ﻋﻨﺪﻣﺎ ﻧﺘﺮك‬
‫}‬
‫اﻟﻨﺸﺎط إﻟﻰ أن ﻳﻨﺘﻬﻰ ﻃﻮل ﻣﻠﻒ اﻟﻮﺳﺎﺋﻂ‬
‫أﻳﻨﻤﺎ ﺗﺮى اﻟﺴﻄﺮ ;)(ــــــــ ‪ super.‬ﻓﺎاﻟﻔﺎﺋﺪة ﻣﻨﻬﺎ ﻫﻮ أن اﻟﻨﺸﺎط ﻳﻌﺮف ﻛﻴﻒ ﻳﻘﻮم ﺑﻬﺬه ﻋﻤﻠﻴﺔ اﺳﻠﻮب ﻻ ﻳﺮاه‬
‫اﻟﻤﺴﺘﺨﺪم وﺗﻘﻮم ﺑﺄﻋﻤﺎل ﺗﻨﻈﻴﻒ اﻟﻤﻮارد اﻟﺘﻲ ﻻﺣﺎﺟﺔ ﻟﻠﻤﻄﻮرﻳﻦ ﺑﻬﺎ وﻟﺬﻟﻚ ﻟﻮ ﺣﺎوﻟﺖ إزاﻟﺔ ﻫﺬا اﻟﺴﻄﺮ ﺳﺘﻈﻬﺮ‬
‫ﻟﻚ أﺧﻄﺎء واﻟﺘﻄﺒﻴﻖ ﻟﻦ ﻳﻌﻤﻞ‬

‫ﺗﺮﻛﻴﺰ اﻟﺼﻮت و ‪AUDIO MANAGER‬‬


‫وﻧﻘﺼﺪ ﺑﺘﺮﻛﻴﺰ اﻟﺼﻮت أﻧﻪ ﻓﻘﻂ اﻟﺘﻄﺒﻴﻘﺎت اﻟﺘﻲ ﺑﻬﺎ ﺗﺮﻛﻴﺰ اﻟﺼﻮت ﺳﺘﻜﻮن ﻗﺎدرة ﻋﻠﻰ ﺗﺸﻐﻴﻞ اﻟﻤﻠﻔﺎت اﻟﺼﻮﺗﻴﺔ‬
‫ﻓﻲ أي وﻗﺖ وﻫﺬا ﻳﻌﻨﻲ ﻓﻲ ﺑﻌﺾ اﻷوﻗﺎت إﻳﻘﺎف ﺗﺸﻐﻴﻞ اﻟﻤﻠﻔﺎت اﻟﺼﻮﺗﻴﺔ وﺗﺸﻐﻴﻞ ﻣﻠﻔﺎت ﺻﻮﺗﻴﺔ أﺧﺮى ذات‬
‫أﻫﻤﻴﺔ أﻛﺒﺮ‬
‫ﻣﺜﺎل ذﻟﻚ ﻟﻮ ﻛﻨﺖ ﺗﺴﺘﻤﻊ إﻟﻰ ﻣﻠﻒ ﺻﻮﺗﻲ ﺛﻢ ﺟﺎءك اﺗﺼﺎل ﻣﻦ أﺣﺪﻫﻢ ﻓﻨﺤﻦ ﺑﺤﺎﺟﺔ إﻟﻰ إﻳﻘﺎف ﻣﻠﻔﻨﺎ اﻟﺼﻮﺗﻲ‬
‫ﻣﺆﻗﺘﺎ ﺛﻢ اﺳﺘﺌﻨﺎﻓﻬﺎ ﺑﻌﺪ اﻟﻤﻜﺎﻟﻤﺔ‬
‫ﺗﺴﺠﻴﻞ ﻣﺴﺘﻤﻊ أﺣﺪاث‬ ‫ﺗﺮك ﺗﺮﻛﻴﺰ اﻟﺼﻮت‬ ‫ﻃﻠﺐ ﺗﺮﻛﻴﺰ اﻟﺼﻮت‬
‫ﻟﻠﺘﺤﻜﻢ ﻓﻲ ﻫﺬه ﺗﺮﻛﻴﺰ اﻟﺼﻮت ‪Register a listener Abandon Audio Foucs Request Audio Foucs‬‬
‫ﻧﺴﺘﻌﻤﻞ اﻟﺼﻨﻒ ‪ AudioManager‬ﻋﻨﺪﻣﺎ ﻧﻜﻮن ﺑﺤﺎﺟﺔ إﻟﻰ ﻳﺴﻤﺢ ﻟﻨﺎ ﺑﺎﻟﺘﺨﻠﻲ ﻋﻦ ﻣﺴﺘﻤﻊ أﺣﺪاث ﻟﻤﻌﺮﻓﺔ‬
‫ﺗﺸﻐﻴﻞ ﻣﻠﻒ ﺻﻮﺗﻲ ﺗﺮﻛﻴﺰ اﻟﺼﻮت ﻓﻴﻤﺎ ﺑﻌﺪ ﺣﺎﻟﺔ ﺗﺮﻛﻴﺰ اﻟﺼﻮت‬ ‫وﻟﻪ ﺛﻼث ﻃﺮق ‪Methods‬‬
‫ﻳﻌﺘﺒﺮ ﺻﻨﻒ ﻣﺪﻳﺮ اﻟﺼﻮت ‪ AudioManager‬ﺧﺪﻣﺔ ‪ Service‬ؤأي ﺧﺪﻣﺔ ﻣﻦ ﺧﺪﻣﺎت ﻧﻈﺎم اﻷﻧﺪرﻳﻮد ﻫﻲ ﻓﻲ اﻷﺻﻞ‬
‫ﺻﻨﻒ ‪ Class‬ﻳﺮﺟﻊ إﻟﻴﻪ اﻟﻨﻈﺎم‬
‫ﺗﻌﺮﻳﻒ ﻣﺘﻐﻴﺮ ﺟﺪﻳﺪ ﻟﻤﺪﻳﺮ اﻟﺼﻮت ‪//‬‬
‫;‪private AudioManager mAudioManager‬‬
‫ﻣﺴﺘﻤﻊ اﻷﺣﺪاث ﻫﺬا ﻳﻌﻤﻞ ﻋﻨﺪﻣﺎ ﻳﺘﻐﻴﺮ ﺗﺮﻛﻴﺰ اﻟﺼﻮت**‪/‬‬
‫ﺑﺴﺒﺐ اﻧﺘﻘﺎل ﺗﺮﻛﻴﺰ اﻟﺼﻮت إﻟﻰ ﺗﻄﺒﻴﻘﺎت أﺧﺮى ﻓﻲ اﻟﺠﻬﺎز‪ ،‬ﻣﺜﻼ ﺻﻮت اﺗﺼﺎل‬
‫‪*/‬‬
‫{ )(‪private AudioManager.OnAudioFocusChangeListener mOnAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener‬‬
‫‪@Override‬‬
‫اﻟﻄﺮﻳﻘﺔ اﻟﻤﺴﺆوﻟﺔ ﻋﻦ ﻣﺮاﻗﺒﺔ ﺗﻐﻴﺮ ﺗﺮﻛﻴﺰ اﻟﺼﻮت ‪//‬‬
‫{ )‪public void onAudioFocusChange(int focusChange‬‬
‫ﻫﺬا اﻟﺴﻄﺮ ﺳﻴﺤﺪد ﻧﻮع اﻟﺘﺮﻛﻴﺰ اﻟﺬي ﺣﺼﻞ ﻋﻠﻰ اﻟﺼﻮت ‪//‬‬
‫{ )‪if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK‬‬
‫ﻳﻘﺼﺪ ﻣﻨﻪ أﻧﻨﺎ ﻓﻘﺪﻧﺎ اﻟﺼﻮت ﻟﻔﺘﺮة ﺑﺴﻴﻄﺔ ‪// AUDIOFOCUS_LOSS_TRANSIENT‬‬
‫ﻳﻘﺼﺪ ﻣﻨﻪ أﻧﻪ ﻳﺴﻤﺢ ﻟﻠﺘﻄﺒﻴﻖ ﺑﻤﻮاﺻﻠﺔ ﺗﺸﻐﻴﻞ اﻟﺼﻮت ﻟﻜﻦ ﺑﺼﻮت ﻣﻨﺨﻔﺾ ‪// AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK‬‬

‫‪45‬‬
‫ﺗﺎﺑــﻊ‬ AUDIO MANAGER ‫ﺗﺮﻛﻴﺰ اﻟﺼﻮت و‬
// ‫إﻳﻘﺎف ﻣﺆﻗﺖ ﻟﻠﺼﻮت‬
mMediaPlayer.pause();
// ‫إﻋﺎدة ﻣﻠﻒ اﻟﺼﻮت إﻟﻰ اﻟﺒﺪاﻳﺔ ﻷن ﻓﻲ ﺣﺎﻟﺘﻨﺎ ﻫﺬه ﻧﺮﻳﺪ ﺳﻤﺎع اﻟﻜﻠﻤﺎت ﻣﻦ اﻟﺒﺪاﻳﺔ ﺑﻌﺪ ﺗﻐﻴﺮ ﺗﺮﻛﻴﺰ اﻟﺼﻮت‬
mMediaPlayer.seekTo(0);
// AUDIOFOCUS_GAIN ‫ﻳﻘﺼﺪ ﺑﻪ أﻧﻨﺎ ﺣﺼﻠﻨﺎ ﻋﻠﻰ ﺗﺮﻛﻴﺰ اﻟﺼﻮت ﻣﺮة أﺧﺮى وﻧﺴﺘﻄﻴﻊ ﺗﺸﻐﻴﻞ اﻟﺼﻮت اﻵن‬
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
mMediaPlayer.start();
// AUDIOFOCUS_LOSS ‫ﻳﻘﺼﺪ ﺑﻪ أﻧﻨﺎ ﻓﻘﺪﻧﺎ ﺗﺮﻛﻴﺰ اﻟﺼﻮت وﻧﻘﻮم ﺑﺈﻳﻘﺎف اﻟﺘﺸﻐﻴﻞ وﻧﺤﺬف ﻣﻮارد ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ‬
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
// ‫اﻹﻧﺘﻘﺎل إﻟﻰ اﻟﻄﺮﻳﻘﺔ اﻟﺘﻲ ﻓﻴﻬﺎ ﺣﺬف ﻣﻮارد ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ وﻛﺬﻟﻚ إﻳﻘﺎف ﺗﺴﺠﻴﻞ ﻣﺪﻳﺮ اﻟﺼﻮت‬
releaseMediaPlayer();
}}
};
// AUDIOFOCUS_GAIN_TRANSIENT. ‫ﻃﻠﺐ ﺗﺮﻛﻴﺰ اﻟﺼﻮت ﻟﺘﺸﻐﻴﻞ اﻟﻤﻠﻒ اﻟﺼﻮﺗﻲ ﻟﻔﺘﺮة ﺑﺴﻴﻄﺔ‬
int result = mAudioManager.requestAudioFocus(mOnAudioFocusChangeListener,
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
// ‫اﻟﺘﺄﻛﺪ ﻣﻦ اﻟﺤﺼﻮل ﻋﻠﻰ ﺗﺮﻛﻴﺰ اﻟﺼﻮت‬
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// ‫ﺣﺼﻠﻨﺎ ﻋﻠﻰ ﺗﺮﻛﻴﺰ اﻟﺼﻮت‬

// ‫ﺗﺠﻬﻴﺰ ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻆ ﺑﻤﻠﻒ اﻟﺼﻮت اﻟﻤﻄﻠﻮب‬


mMediaPlayer = MediaPlayer.create(ColorsActivity.this, word.getAudioResourceId());

// ‫ﺗﺸﻐﻴﻞ اﻟﺼﻮت‬
mMediaPlayer.start();

// ‫ﺗﺠﻬﻴﺰ ﻣﺴﺘﻤﻊ أﺣﺪاث ﻟﻤﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ ﻟﻠﺘﻤﻜﻦ ﻣﻦ إﻳﻘﺎف اﻟﺼﻮت وﺣﺬف اﻟﻤﻮارد إذا اﻧﺘﻬﻰ اﻟﻤﻠﻒ اﻟﺼﻮﺗﻲ‬
mMediaPlayer.setOnCompletionListener(mCompletionListener);
}
// ‫ﻋﻨﺪﻣﺎ ﻧﻘﻮم ﺑﺈزاﻟﺔ ﺟﻤﻴﻊ ﻣﻮارد ﻣﺸﻐﻞ اﻟﻮﺳﺎﺋﻂ ﻓﻜﺬﻟﻚ ﻧﻘﻮم ﺑﺈﻳﻘﺎف وﻇﺎﺋﻒ ﻣﺪﻳﺮ اﻟﺼﻮت ﺑﻐﺾ اﻟﻨﻈﺮ ﻛﺎن ﻫﻨﺎ ﺗﺮﻛﻴﺰ ﻟﻠﺼﻮت أم ﻻ‬
private void releaseMediaPlayer() {
// If the media player is not null, then it may be currently playing a sound.
if (mMediaPlayer != null) {
// Regardless of the current state of the media player, release its resources
mMediaPlayer.release();
mMediaPlayer = null;
mAudioManager.abandonAudioFocus(mOnAudioFocusChangeListener);
}
}

46
‫ﺗﺎﺑــﻊ‬ ‫ﺗﺮﻛﻴﺰ اﻟﺼﻮت و ‪AUDIO MANAGER‬‬

‫ﺣﺎﻻت ﺗﺮﻛﻴﺰ اﻟﺼﻮت‬ ‫اﻟﺘﺄﺛﻴﺮ ﻋﻠﻰ ﺗﺮﻛﻴﺰ اﻟﺼﻮت‬

‫‪AUDIOFOCUS_GAIN‬‬ ‫إﻋﺎدة اﻟﺤﺼﻮل ﻋﻠﻰ ﺗﺮﻛﻴﺰ اﻟﺼﻮت‬

‫‪AUDIOFOCUS_LOSS‬‬ ‫ﻓﻘﺪان ﺗﺮﻛﻴﺰ اﻟﺼﻮت ﻛﻠﻴﺎ‬

‫‪AUDIOFOCUS_LOSS_TRANSIENT‬‬ ‫ﻓﻘﺪان ﺗﺮﻛﻴﺰ اﻟﺼﻮت ﻣﺆﻗﺘﺎ‬

‫ﻓﻘﺪان ﺗﺮﻛﻴﺰ اﻟﺼﻮت ﻣﺆﻗﺘﺎ ﻟﻜﻦ ارﺗﻔﺎع ﻣﺴﺘﻮى اﻟﺼﻮت‬


‫‪AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK‬‬
‫ﺗﻢ ﺗﺨﻘﻴﻀﻪ‬

‫اﻹﺳﺘﺠﺎﺑﺔ ﻟﻠﻤﺲ ‪TOUCH FEEDBACK‬‬


‫ﻧﺴﺘﻄﻴﻊ أن ﻧﺠﻌﻞ ﻛﻞ ﻋﻨﺼﺮ ﻋﺮض ﻓﻲ اﻟﺸﺎﺷﺔ ﻗﺎﺑﻞ ﻟﻠﻤﺲ وﻳﻤﻜﻦ ﻋﻨﺪ ﻟﻤﺴﻪ أن‬
‫ﻳﻈﻬﺮ ﻧﻤﻂ ﻣﺮﺋﻲ و ﺣﺮﻛﻲ وذﻟﻚ ﺑﺈﺿﺎﻓﺔ ﻫﺬا اﻟﺴﻄﺮ ﻷﻛﻮاد ‪ XML‬ﻟﻌﻨﺼﺮ اﻟﻌـﺮض‬
‫”‪android:background = “?android:attr/selectableItemBackground‬‬
‫ﻳﺘﻐﻴﺮ ﻫﺬا اﻟﻨﻤﻂ اﻟﺤﺮﻛﻲ ﺑﻴﻦ ﻧﺴﺦ ﻧﻈﺎم أﻧﺪرﻳﻮد ؤإﻟﻰ وﻓﻲ اﻟﻨﻈﺎم اﻟﻘﺪﻳﻢ ﻛﺎن‬
‫ﻳﻈﻬﺮ ﻓﻘﻂ ﻣﺮﺑﻊ ﻋﻠﻰ ﻋﻨﺎﺻﺮ اﻟﻌﺮض ﻋﻨﺪ ﻟﻤﺴﻬﺎ‬
‫‪<FrameLayout‬‬ ‫ﻷﻧﻨﺎ ﻏﻴﺮﻧﺎ ﻣﻴﺰة اﻟﺨﻠﻔﻴﺔ ﻟﻌﻨﺼﺮ اﻟﻌﺮض‬
‫"‪android:layout_width="match_parent‬‬
‫"‪android:layout_height="wrap_content‬‬ ‫ﻟﻌﺮض ﺣﺮﻛﺎت اﻟﻠﻤﺲ ﻓﺈﻧﻨﺎ ﻓﻘﺪﻧﺎ‬
‫>"‪android:background="@color/category_family‬‬ ‫اﻟﺨﻠﻔﻴﺔ اﻟﻤﻠﻮﻧﺔ ﻓﻠﺤﻞ ﻫﺬه اﻟﻤﺸﻜﻠﺔ‬
‫‪<TextView‬‬ ‫ﻧﻀﻊ ﻋﻨﺼﺮ اﻟﻌﺮض اﻟﺬي ﻧﺤﺘﺎﺟﻪ داﺧﻞ‬
‫"‪android:background="?android:attr/selectableItemBackground‬‬ ‫ﺗﺨﻄﻴﻂ ‪ FrameLayout‬ﻛﻤﺎ ﻓﻲ اﻟﻤﺜﺎل‬
‫>‪android:text="@string/category_family" /‬‬
‫>‪</FrameLayout‬‬

‫‪<ListView‬‬ ‫ﻳﻤﻜﻦ ﺗﻔﻌﻴﻞ ﻋﻼﻣﺎت اﻟﻠﻤﺲ ﻋﻠﻰ‬


‫"‪android:id="@+id/list‬‬ ‫ﻋﻨﺎﺻﺮ اﻟﻘﺎﺋﻤﺔ ‪ ListView‬ﺑﺘﻔﻌﻴﻞ ﻣﻴﺰة‬
‫"‪android:orientation="vertical‬‬ ‫رﺳﻢ ﻣﺆﺷﺮ اﻟﻠﻤﺲ ﻓﻘﻂ اﻟﻌﻨﺎﺻﺮ‬
‫"‪android:layout_width="match_parent‬‬
‫"‪android:layout_height="match_parent‬‬ ‫اﻟﻤﻀﻤﻨﺔ‬
‫>‪android:drawSelectorOnTop="true"/‬‬ ‫"‪android:drawSelectorOnTop="true‬‬

‫‪47‬‬
‫‪APPENDIX: ATTRIBUTES ILLUSTRATION‬‬ ‫اﻟﻤﻠﺤﻘﺎت‪ :‬ﺗﻮﺿﻴﺢ اﻟﻤﻤﻴﺰات‬

‫وﺻﻒ اﻟﻤﻴﺰة‬ ‫اﻟﻤﻤﻴـــﺰات‬ ‫وﺻﻒ اﻟﻤﻴﺰة‬ ‫‪dpi‬‬ ‫اﻟﻤﻤﻴـــﺰات‬


‫‪ android:src‬ﺗﺤﺪﻳﺪ اﻟﺼﻮرة ﻟﻌﻨﺼﺮ اﻟﺮﺳﻮﻣﻴﺎت‬ ‫‪ android:text‬اﻟﻨﺺ اﻟﻤﺮاد ﻋﺮﺿﻪ‬
‫‪ android:scaleType‬اﻟﺘﺤﻜﻢ ﻓﻲ ﻃﺮﻳﻘﺔ ﺗﺤﺠﻴﻢ اﻟﺼﻮرة داﺧﻞ اﻟﻌﻨﺼﺮ‬ ‫إﻇﻬﺎر اﻟﻨﺼﻮص ﺑﺎﻷﺣﺮف اﻟﻜﺒﻴﺮة ‪Capital Letter‬‬ ‫‪android:textAllCaps‬‬
‫‪ android:maxWidth‬ﺗﺤﺪﻳﺪ اﻟﻌﺮض اﻷﻗﺼﻰ ﻟﻬﺬا اﻟﻌﻨﺼﺮ‬ ‫‪ android:textAppearance‬إﻇﻬﺎر اﻟﻨﺺ ﺑﻠﻮن‪ ،‬ﺣﺠﻢ‪ ،‬ﻧﻮع ﺧﻂ وﺗﻨﺴﻴﻖ ﻣﻨﺎﺳﺐ ﺑﺈﺧﺘﻼف اﻷﺟﻬﺰة‬
‫‪ android:maxHeight‬ﺗﺤﺪﻳﺪ اﻟﻄﻮل اﻷﻗﺼﻰ ﻟﻬﺬا اﻟﻌﻨﺼﺮ‬ ‫‪ android:textColor‬ﻟـــﻮن اﻟﻨﺺ‬
‫‪ android:cropToPadding‬اﻗﺘﺼﺎص اﻟﺼﻮرة إﻟﻰ ﺣﺪود اﻟﺤﺸﻮ اﻟﺪاﺧﻠﻴﺔ ﻟﻠﻌﻨﺼﺮ‬ ‫‪ android:textSize‬ﺣﺠﻢ اﻟﻨﺺ ﻳﻘﺎس ﺑﻌﺪة وﺣﺪات ‪sp, px, dp, in, mm‬‬
‫ﺗﻮﺳﻴﻂ اﻟﺼﻮرة داﺧﻞ اﻟﻌﻨﺼﺮ ﺑﺎﻟﻨﺴﺒﺔ ﻟﻠﺤﺪ اﻟﺴﻔﻠﻲ‬ ‫‪android:baselineAlignBottom‬‬ ‫‪ android:textStyle‬ﺗﻨﺴﻴﻖ اﻟﻨﺺ )ﻏﺎﻣﻖ‪ ،‬ﻣﺎﺋﻞ‪ ،‬ﻏﺎﻣﻖ وﻣﺎﺋﻞ(‬
‫‪ android:baseline‬ﻧﺴﺒﺔ اﻹﻧﺤﺮاف ﻟﻠﻌﻨﺼﺮ داﺧﻞ ﻣﺤﺘﻮاه‬ ‫‪ android:singleLine‬إﻇﻬﺎر اﻟﻨﺺ ﻓﻲ ﺳﻄﺮ واﺣﺪ ﻓﻘﻂ ﻳﻤﻜﻦ ﺗﻤﺪﻳﺪه ﺑﺸﻜﻞ أﻓﻘﻲ ﻓﻘﻂ‬
‫‪ android:tint‬ﻓﻠﺘﺮ اﻷﻟﻮان اﻟﻤﺴﺘﺨﺪم ﻓﻲ ﺻﻮرة اﻟﻌﻨﺼﺮ‬ ‫‪ android:minLines‬ﺗﺤﺪﻳﺪ اﻟﺤﺪ اﻷدﻧﻰ ﻟﻌﺪد اﻟﺴﻄﻮر ﻓﻲ ﻋﻨﺼﺮ ﻛﺘﺎﺑﺔ اﻟﻨﺺ‬
‫‪ android:tintMode‬ﻧﻮع ﻓﻠﺘﺮ اﻷﻟﻮان اﻟﻤﺴﺘﺨﺪم ﻓﻲ ﺻﻮرة اﻟﻌﻨﺼﺮ‬ ‫‪ android:typeface‬ﻧﻮع اﻟﺨﻂ اﻟﻤﻌﺮوض ﻓﻲ اﻟﻌﻨﺼﺮ‬
‫‪ android:shadowRadius‬ﻣﻘﺪار ﺗﻤﻮﻳﻪ ﺗﻨﺴﻴﻖ اﻟﻈﻼل ﻟﻠﻌﻨﺼﺮ‬
‫‪ android:shadowDy‬ﺗﺤﺮك اﻟﻈﻼل ﺗﺤﺖ اﻟﻌﻨﺼﺮ ﻓﻲ اﻹﺗﺠﺎه اﻟﻌﻤﻮدي‬
‫‪ android:shadowDx‬ﺗﺤﺮك اﻟﻈﻼل ﺗﺤﺖ اﻟﻌﻨﺼﺮ ﻓﻲ اﻹﺗﺠﺎه اﻷﻓﻘﻲ‬
‫‪ android:shadowColor‬ﻟﻮن اﻟﻈﻼل ﻟﻠﻌﻨﺼﺮ‬
‫‪ android:selectAllOnFocus‬ﺗﺤﺪﻳﺪ اﻟﻨﺺ ﺑﺎﻟﻜﺎﻣﻞ إذا ﺗﻢ ﺗﺮﻛﻴﺰ اﻟﻤﺆﺷﺮ ﻋﻠﻰ اﻟﻌﻨﺼﺮ‬
‫‪ android:scrollHorizontally‬اﻟﺘﺤﺮﻳﻚ اﻷﻓﻘﻲ ﻟﻠﻤﺤﺘﻮﻳﺎت داﺧﻞ اﻟﻌﻨﺼﺮ‬
‫‪ android:phoneNumber‬ﺗﺤﺪﻳﺪ ﻣﺎ إذا ﻛﺎن اﻟﻌﻨﺼﺮ ﻳﺤﺘﻮي ﻧﺺ ﺑﺘﻨﺴﻴﻖ رﻗﻢ ﻫﺎﺗﻒ‬
‫‪ android:password‬ﺗﺤﺪﻳﺪ إﻇﻬﺎر اﻟﺤﺮوف اﻟﻤﻜﺘﻮﺑﺔ ﻓﻲ اﻟﻌﻨﺼﺮ أو إﻇﻬﺎر رﻣﻮز ﻛﻠﻤﺔ ﺳﺮ‬
‫‪ android:numeric‬ﺗﺤﺪﻳﺪ ﻃﺮﻳﻘﺔ اﻟﻜﺘﺎﺑﺔ ﻓﻲ اﻟﻌﻨﺼﺮ إﻟﻰ ﻛﺘﺎﺑﺔ أﻋﺪاد ﻓﻘﻂ‬
‫‪ android:lines‬ﻋﺪد اﻷﺳﻄﺮ ﻟﻠﻨﺺ اﻟﻤﺮاد ﻋﺮﺿﻪ ﻓﻲ اﻟﻌﻨﺼﺮ‬
‫‪ android:gravity‬ﺗﺤﺪﻳﺪ ﻣﺤﺎذاة داﺧﻞ اﻟﻌﻨﺼﺮ إذا ﻛﺎﻧﺖ اﻟﻨﺼﻮص أﺻﻐﺮ ﻣﻦ أﺑﻌﺎد اﻟﻌﻨﺼﺮ‬
‫‪ android:maxLines‬ﺗﺤﺪﻳﺪ اﻟﻌﺪد اﻷﻗﺼﻰ ﻟﻸﺳﻄﺮ اﻟﻤﺮاد ﻋﺮﺿﻬﺎ‬
‫‪APPENDIX: ABBREVIATIONS‬‬ ‫اﻟﻤﻠﺤﻘﺎت‪ :‬اﻟﻜﻠﻤﺎت اﻟﻤﺨﺘﺼﺮة‬

‫وﺻﻒ اﻹﺧﺘﺼﺎر‬ ‫ﻣﻌﻨﻰ اﻹﺧﺘﺼﺎر‬


‫‪dpi‬‬ ‫اﻹﺧﺘﺼـــﺎر‬
‫ﺑﻴﺌﺔ ﺗﻄﻮﻳﺮ ﻣﺘﻜﺎﻣﻠﺔ وﻓﻲ وﺗﺼﻤﻴﻢ ﺗﻄﺒﻴﻘﺎت اﻷﻧﺪرﻳﻮد ﻫﻨﺎ ﺳﺘﻜﻮن اﻟﺒﻴﺌﺔ ﻫﻲ ‪Android Studio‬‬ ‫‪Integrated Development Environment‬‬ ‫‪IDE‬‬
‫ﻫﻲ ﻟﻐﺔ ﺑﺴﻴﻄﺔ وﻣﺮﻧﺔ ﻧﺴﺘﺨﺪﻣﻬﺎ ﻓﻲ ﺗﺼﻤﻴﻢ وﺗﺨﻄﻴﻂ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ‬ ‫‪eXtensible Markup Langauge‬‬ ‫‪XML‬‬
‫ﻫﻮ ﻣﺤﺎﻛﻲ ﺗﻔﺎﻋﻠﻲ ﻳﻘﻮم ﺑﻌﺮض ﻧﺼﻮص اﻟـ ‪ XML‬ﻛﻤﺎ ﻟﻮ ﻛﺎﻧﺖ ﻋﻠﻰ ﺟﻬﺎز أﻧﺪرﻳﻮد ﻓﻌﻠﻲ‬ ‫‪eXtensible Markup Langauge Visualizer‬‬ ‫‪XMLV‬‬
‫وﺣﺪة ﻗﻴﺎس ﻟﻸﺑﻌﺎد ﺗﻘﻮم ﺑﺘﺤﺠﻴﻢ اﻟﻌﻨﺎﺻﺮ ﻓﻲ اﻷﺟﻬﺰة ﺑﺸﻜﻞ ﻣﺘﻨﺎﺳﻖ ﺑﻐﺾ اﻟﻨﻈﺮ ﻋﻦ ﻋﺪد اﻟﺒﻜﺴﻼت‬ ‫‪(Density/Device) - Independent Pixel‬‬ ‫‪dp, dip‬‬
‫وﺣﺪة ﻗﻴﺎس ﺗﺴﺘﺨﺪم ﻟﻠﺨﻄﻮط ﺗﻐﻴﺮ ﺣﺠﻢ اﻟﺨﻄﻮط ﻓﻲ اﻷﺟﻬﺰة ﺑﺸﻜﻞ ﻣﺘﻨﺎﺳﻖ ﺑﻐﺾ اﻟﻨﻈﺮ ﻋﻦ ﻋﺪد اﻟﺒﻜﺴﻼت‬ ‫‪Scale Independent Pixels‬‬ ‫‪sp, sip‬‬
‫ﻣﺴﺎﺣﺔ اﻹﺳﻢ اﻟﺨﺎﺻﺔ ﺑﺎﻟﻤﻤﻴﺰات اﻟﻤﺴﺘﺨﺪﻣﺔ‬ ‫‪eXtensible Markup Langauge namespace‬‬ ‫‪xmlns‬‬
‫ﻣﺴﺎﺣﺔ اﻹﺳﻢ اﻟﺨﺎﺻﺔ ﺑﺎﻟﻤﻤﻴﺰات اﻟﻤﺴﺘﺨﺪﻣﺔ‬ ‫‪Android Debug Bridge‬‬ ‫‪adb‬‬
‫ﻫﻲ أداة ﺗﺴﺘﺨﺪم ﻟﺘﺤﺼﻴﺢ اﻷﺧﻄﺎء ﻓﻲ اﻟﻜﻮدات وﻫﻲ ﻣﻀﻤﻨﺔ ﻓﻲ ﻣﻨﺼﺔ أﻧﺪرﻳﻮد داﺧﻞ اﻟﺤﺰم اﻟﺘﻄﻮﻳﺮﻳﺔ ‪SDK‬‬ ‫‪Dalvik Debug Monitor Service‬‬ ‫‪DDMS‬‬
‫ﻫﻲ أدوات ﺗﻄﻮﻳﺮ اﻟﺘﻄﺒﻴﻘﺎت وﺗﺴﺎﻋﺪ ﻓﻲ ﻋﻤﻞ اﻟﺒﺮﻣﺠﻴﺎت ﻟﻤﺨﺘﻠﻒ اﻟﻤﻨﺼﺎت اﻟﺘﻄﻮﻳﺮﻳﺔ )ﻣﺜﺎل‪ :‬أﻧﺪرﻳﻮد ‪(SDK‬‬ ‫‪Software development kit‬‬ ‫‪SDK‬‬
‫ﻫﻲ أداة ﻣﻀﻤﻨﺔ ﻓﻲ ﺣﺰﻣﺔ أﻧﺪرﻳﻮد اﻟﺘﻄﻮﻳﺮﻳﺔ ﺗﺤﻮل اﻟﻤﻮارد إﻟﻰ أرﻗﺎم ﻣﻌﺮﻓﺔ وﺗﻮﻟﺪ ﻣﻠﻔﺎت اﻟﻤﻀﻐﻮﻃﺔ ‪APK‬‬ ‫‪Android Asset Packaging Tool‬‬ ‫‪AAPT‬‬
‫ﻫﻲ أداة ﺗﻘﻮم ﺑﺒﻨﺎء اﻟﺒﻴﺎﻧﺎت اﻟﻤﻀﻤﻨﺔ ﻓﻲ ﻣﻠﻔﺎت‪ XML‬إﻟﻰ ﻋﻨﺎﺻﺮ واﺟﻬﺔ ﻣﻨﺴﻘﺔ‬ ‫‪Extensible Markup Language Compiler‬‬ ‫‪XMLC‬‬
APPENDIX: REFERENCES ‫ اﻟﻤـــﺮاﺟﻊ‬:‫اﻟﻤﻠﺤﻘــﺎت‬

‫ﻣﺼﺪر اﻟﻤﺮﺟﻊ‬ ‫ﻓﺎﺋﺪة اﻟﻤﺮﺟﻊ‬ dpi ‫اﻟﻤــﺮﺟﻊ‬


https://developer.android.com/index.html ‫ﻣﻮﻗﻊ ﻣﻄﻮري أﻧﺪرﻳﻮد اﻟﺮﺳﻤﻲ‬ Android Developer Website
https://material.io/guidelines/# ‫ﻣﻮﻗﻊ ﻹﺧﺘﻴﺎر اﻟﺘﻨﺴﻴﻘﺎت اﻟﻤﻨﺎﺳﺒﺔ ﻟﻠﺘﻄﺒﻴﻘﺎت‬ Material Design
https://plus.google.com/+AndroidDevelopers/posts/gQuBtnuk6iG ‫( ﻟﻄﻮري اﻷﻧﺪرﻳﻮد‬+) ‫ﺻﻔﺤﺔ ﺟﻮﺟﻞ‬ Android Developpers (g+)
https://developers.google.com/android/for-all/vocab-words/ ‫ﺻﻔﺤﺔ ﻣﺮﺟﻊ اﻟﺘﻌﺒﻴﺮات اﻟﺒﺮﻣﺠﻴﺔ ﻟﻸﻧﺪرﻳﻮد‬ Android Vocab Glossary
http://labs.udacity.com/android-visualizer/ XML ‫ﻣﺤﺎﻛﻲ وﻫﻤﻲ ﻟﺘﺼﻤﻴﻢ واﺟﻬﺎت اﻟﺘﻄﺒﻴﻘﺎت‬ Android Visualizer
https://stackoverflow.com/questions/tagged/android ‫ﻣﻮﻗﻊ ﻓﻴﻪ إﺟﺎﺑﺎت اﻟﻜﺜﻴﺮ ﻣﻦ اﻷﺳﺌﻠﺔ اﻟﻤﺘﻌﻠﻘﺔ ﺑﺎﻟﺒﺮﻣﺠﺔ‬ Stackoverflow
https://drive.google.com/file/d/0B5XIkMkayHgRMVljUVIyZzNmQUU/view ‫ﻳﺤﺘﻮي ﻛﻮدات ﺑﻌﺾ ﻋﻨﺎﺻﺮ ﺗﺼﻤﻴﻢ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻖ‬ Common Views Cheatsheet
https://www.w3schools.com/colors/colors_hex.asp ‫اﻷﻟﻮان اﻟﺴﺪاﺳﻴﺔ اﻟﻤﺴﺘﺨﺪﻣﺔ ﻓﻲ واﺟﻬﺔ اﻟﺘﻄﺒﻴﻘﺎت‬ Hex Colors List
https://en.wikipedia.org/wiki/Android_version_history ‫ﻣﻘﺎﻟﺔ ﻋﻦ ﺗﺎرﻳﺦ إﺻﺪارات أﻧﺪرﻳﻮد‬ Android version history
https://developer.android.com/studio/run/oem-usb.html ‫ﺑﺮاﻣﺞ اﻟﺘﻌﺮف ﻋﻠﻰ اﻷﺟﻬﺰة أﻧﺪرﻳﻮد‬ Install OEM USB Drivers
https://www.udacity.com/course/how-to-use-git-and-github--ud775 ‫دورة اﻟﺘﺤﻜﻢ ﺑﺎﻹﺻﺪار اﻟﺘﺪرﻳﺒﻴﺔ‬ How to Use Git and GitHub
https://twitter.com/AndroidDev ‫ﺻﻔﺤﺔ ﺗﻮﻳﺘﺮ ﻟﻤﻄﻮري اﻷﻧﺪرﻳﻮد‬ Android Developers on twitter
https://www.youtube.com/user/GoogleDevelopers ‫ﺻﻔﺤﺔ ﻳﻮﺗﻴﻮب ﻟﻤﻄﻮري اﻷﻧﺪرﻳﻮد‬ Android Developers on Youtube
https://chris.banes.me/ ‫ﺻﻔﺤﺔ ﺧﺎﺻﺔ ﻟﻤﻄﻮر اﻷﻧﺪرﻳﻮد ﻓﻴﻬﺎ ﻣﻮاﺿﻴﻊ ﻣﻬﻤﺔ‬ Chris Banes (Android Developer)
https://blog.stylingandroid.com/ ‫ﺻﻔﺤﺔ ﺧﺎﺻﺔ ﻟﺘﻨﺴﻴﻘﺎت اﻷﻧﺪرﻳﻮد اﻟﺠﺪﻳﺪة‬ Styling Android
http://fragmentedpodcast.com/ ‫ﻣﻮﻗﻊ ﻟﺒﺚ ﺑﻮدﻛﺎﺳﺖ ﻟﻤﻄﻮري اﻷﻧﺪرﻳﻮد‬ Android Developer Podcast
https://developer.android.com/studio/intro/index.html ‫اﺧﺘﺼﺎرات ﻟﻮﺣﺔ اﻟﻤﻔﺎﺗﻴﺢ ﻷﻧﺪرﻳﻮد اﺳﺘﻮدﻳﻮ‬ Android Studio Shortcut keys
https://www.jetbrains.com/help/idea/editor-basics.html ‫ﻛﻴﻒ ﺗﻌﻴﺪ ﺻﻴﺎﻏﺔ اﻟﺘﻌﻠﻴﻤﺎت اﻟﻤﺼﺪر‬ Editor basics
https://appicon.co/ ‫ﻣﻮﻗﻊ ﻳﻘﻮم ﺑﺘﺤﺠﻴﻢ اﻟﺼﻮر ﻟﻠﺘﻄﺒﻴﻘﺎت‬ App Icon Generator
https://www.materialpalette.com ‫ﻣﻮﻗﻊ ﻳﻌﻄﻴﻚ ﻗﻮاﻟﺐ ﺳﻤﺎت ﻟﻠﺘﻄﺒﻴﻖ‬ Material Palette

Vous aimerez peut-être aussi