Uploaded by jmhjhghj fdfgdgf

androidkotlin

advertisement
ListView
هو طريقة نستخدمهة علمود نسوي لست بيانات علا شكل لستة
طبعا لستة بدون بيانات ما تسوة اي شي نحتاج ادابتر هذه ادابتر نستخدمة علمود نربط المصفوفة بل لست فيو
يعني ال ادابتر ياخذ البيانات وا يحولهة الا لست فيو
طريقة ستخدام لست فيو
اول شي نضيفهة بكود اكس ام ل
var arrayoflist:Array<String>=arrayOf("a")
var adabter:ArrayAdapter<String> = ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,arrayoflist)//هنا مررنة كونتيكس اول باراميتر اما ثاني باراميتر ستخدمنة مكتبة اندرويد حتة نوصل لملف اكس ام ل هذه ملف بي نصوص ال اتيم
اما ثالث باراميتر هو مصفوفة رح يتبدل بي القيم لل ايتم
listview.adapter = adabterlist //هنا ربطنة لست فيو بل ادابتر
-----------------
RecyclerView
هو عبارة عن طريقة لعرض البينات علا شكل قائمة سواء كانت عامودية ام افقية او علا شكل شبكية كراد
يعتبر ريساكل فيو اخف وا اسرع علا ذاكرة من لستفيو حيث يتم عمل ريسايكلر او اعادة تدوير لل عناصر كلما قمنا بعمل سكرول لل لست
بل ريسايكل فيو العناصر من تختفي يعني من نسوي سكرول العناصر ماراح تدمر بل رح تبقة ونكدر هم نستخدمهن من جديد يعني اعادة ستخدام العناصر
هذه الخاصية رح توفر مزيد من طاقة وا توفر مزيد من الاستجابة لل تطبيق
-
نكدر نستخدمة حتة نزل بل عناصر يعني نسوي سكرول فيو
اول شي رح نضيف ال ريسايكلر فيو بل اكتفتي اكس ام ال
ثاني شي نسوي لست رو بعدين رح نسوي كومباين مع ريسايكلر فيو
يعني نسوي ملف اكس م ل بي صفوف يعني التصميم مو احنة من نستخدم ريساكلر فيو حتة نعرض تصميم علا شكل قائمة
بعدين نسوي كلاس هذه كلاس بي معلومات ال صفوف يعني بيانات الي رح نضيفهة بل ريسايكلر فيو
بعدين نسوي كلاس ادابتر هذه ال ادابتر رح يربط البيانات بل ريسايكلر فيو
-
متطلبات
add the implementation("androidx.recyclerview:recyclerview:")
// For control over item selection of both touch and mouse driven selection
implementation("androidx.recyclerview:recyclerview-selection:1.1.0")
to the build graidl moudel app
xml file contain recycleview
xml file contain the design
data model class hold our data we want to show to the recycleview
adapter class that well bind the data to the recycleview
the adapter class code
class TodoAdapter (var todos:List<Todo>): RecyclerView.Adapter<TodoAdapter.TodoViewHolder>() {//هنا نرثث ال ادابتر وا نحدد ال فيوهولدر الي نريد نتعامل ويا
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder {//هذه الدالة تستخدم لي انشاء نسخة لل فيوهولدر لكل عنصر val binding: ItemTodoBinding = ItemTodoBinding.inflate(LayoutInflater.from(parent.context), parent, false)//هنا وسينة انفليت لل عناصر ال باراميتر الي بل دالة فروم هوة يمثل الحاوي الي رح يحتوي العناصر الي سوينالهة انفليت لذالك استخدمنة الكونتيكست ماتة حتة نعطي معلومات حوله لل دالة انفليت
return TodoViewHolder(binding)//هنا ارجعنة نسخة من فيوهولدر يحتوي علا العنصر الي سوينالة انفليت
}
override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {// هذه الدالة تستخدم لي ربط البيانات في العناصر باراميتر الاول هولدر يستخدم لل وصول لل عناصر باراميتر الثاني يشير الا اماكن العناصر الموجودة في ريسايكلفيو وا هذه الدالة ايضا تستدعا لكل عنصر مرة واحدة
holder.binding.apply {//هنا عبر هولدر الي هوة كائن من فيو هولدر وا عبر البايندانك نوصل لل عناصر tvtext.text = todos[position].title//now we use the position like in index to accsice the data in the todos class and call the title to get the value of it and make it for the text same for the second item
checkdone.isChecked = todos[position].ischecked//hair we see for the position 1 make the value ischeked
}//the binding function well called one for each item in recycle view }
override fun getItemCount(): Int {//هذه دالة ترجع عدد العناصر الموجودة في ريسايكلفيو
return todos.size
}
inner class TodoViewHolder(val binding: ItemTodoBinding) ://view holder هذه انر كلاس نستخدمة علمود نخلي مرجع لل عناصر وا نستخدمة حتا نتحكم في العناصر ياخذ باراميتر هذه الباراميتر يمثل العناصر الي رح تضهر بل ريسايكلفيو
RecyclerView.ViewHolder(binding.root) {
}
}
------
هسة نجي لل كود ال مين اكتفتي var todolist = mutableListOf(//هنا سوينة لستة نخلي بيهة البيانات الي نريدهة تضهر بل ريسايكلفيو
Todo("learn hacking",true)
,Todo("learn hacking a+",true)
)
val adapter = TodoAdapter(todolist)//هنا انشئنة كائن من ادابتر وا مهدنة قيمتة بل لستة الي ناشئناها
binding.reco.adapter = adapter//هنا خلينة ال ادابتر مال ريسايكلفيو بل ادابتر الي انشئنا
binding.reco.layoutManager = LinearLayoutManager(this)//هذه لياوت مانجر يستخدم للتحكم في طريقة عرض العناصر في ريسايكلفيو
--
viewholder نستخدمة علمود نعطي مرجع لل عنصر الي نريدة يضهر بل ريسايكلفيو وا نستخدمة علمود نتحكم في ضهور العناصر في الريسايكل فيو
ال باراميتر الدالخ ال فيوهولدر يمثل جميع العناصر الي بل تصميم يعني ال باراميتر يحتوي علا جميع العناصر
adapter هوة المسئول علا ربط البيانات في الريسايكلفيو عبر فيوهولدر
onCreateViewHolder() هذه الدالة المسئولة علا انشاء نسخة فيوهولدر لكل عنصر في ريسايكلفيو تستدعا كلما عنصر اراد الضهور في الريسايكلفيو
الفائدة من انشاء نسخة من فيوهولدر حتة كل ما اراد اعادة استخدام ريسايكل يعني كل ما نسوي سكرول ما ننشء نسخة جديدة بل نعيد استخدامها لذالك النسخ مجرد لل عناصر الي تريد تضهر داخل هذه الدالة نسوي انفليت لل ملف التصميم الي بي العناصر الي نريدها تضهر لل ريسايكلفيو
وراهة ننشئ نسخة من الفيوهولدر وا نمررلة ال فيو ال سوينالة انفليت ك باراميتر وراهة نرجع الكلاس الي ستخدمنا
يعني الدالة تستدعا كلما المستخدم قام بعمل سكرول
وا الدالة مسئولة علا انشائ نسخة من فيوهولدر لكل عنصر
ال باراميتر الاول الي هوة ال
parent
يمثل ال حاوي الي رح يحتوي علا العناصر الي نسويلهة انفليت بحالتنة هوة ال ريسايكلفيو
ال دالة فورم تاخذ كونتيكست لذالك رح نستخدم ال parent.context
انو نعطي معلومات لل دالة انفليت حول الفيوكروب onBindViewHolder() تستخدم هذه الدالة حتة تربط بيانات بل عناصر يعني تستتقبل بيانات مثلا مصفوفة نربط هذه المصفوفة بل عناصر ال فيو نوصل لل عناصر
عبر ال فيو هولدر وا نخليلهم البيانات يعني تستقبل هذه الدالة بيانات عبر هذه الدالة رح نوصل لل فيوهولدر وا عبر فيوهولدر نوصلل لل فيوز ونمرر الهم البيانات
-----------------
cheack box
اول شي ننشء دالة اونكلك نخليهة نفس الاسم لكل ال شيك بوكس
بعدين نسوي كاستنج لل فيو وراهة نسوي متغير بوليان قيمتة تكون فيو
من رح ينضغط عل شيك بوكس هية القيمة تلقائيا رح تصير ترو وذا شال الضغط رح تصير فالس
مثال لنفترض انو سوينة الدالة بملف ال اكس ام ل وا جهزنة التصميم هسة رح نسوي المثال بل كود
fun onclicknamefunction(view:View)
{
view as CheckBox
var x:Boolean = view.isChecked //isChecked هاي نستخدمهة من المستخدم يضغط عل زر رح تحدد اذا جان ترو او فالس
when(view.id)//هل قيمة بداخل الاقواس هو ال معرف مال الفيو رح نسوي عليه حتمالات
{
R.id.idofcheckbox -> if(x){log.d("idis","true"}else{log.d("idis","false"}
}
}
-----
TextUtils هو كلاس يجي وية الاندرويد يسمحنة ان نتئكد من عنصر معين فارغا ام لا
هناك دالة موجودة داخل الكلاس تستخدم لل تئكد من اذا كان العنصر فارا ام لا مثال
TextUtils.isEmpty(هنا نكتب العنصر مثلا حقل ادخال )
---------
الوان بل اندرويد عبارة عن انتجر
-------
style.xml
رح نستهخدم الملف علمود نصمم العناصر مالتنة اول شي نبدي <style name="هنا نكتب اسم ال ستايل حتة نوصلة ">
<item name="android:textSize">value</item>//ال ايتم نستخدمهة علمود نكتب التصميم مالتنة يعني نحدد تصميم العناصر
نكتب android:
حتة نختار قيم التصميم
</style>
مثال حول ستدعاء في ملف اكتفتي xml
نكتب
style="name the file" اسم ملف الستايل -------------------
colorprimary
هو الي رح نغير لون ال بار colorprimary اما
هوة الي يغير لون الشريط الفوك الي نزل منة البردة
coloraccent
نستخدمة حتة نغيري الوان العناصر من داخل
مثلا شيك بوكس نريد من واحد يضغط عليه يصير لون المربع داخلي احمر او اصفر الخ
------
تكدر تغير الثيم بملف ال ستايل
يعني تكدر تغير لون ال بار لون ال توب بار هم تكدر تحدد نص معين حجمة يكون مثلا 10 هسة اي نص رح ينضاف رح يكون حجمة 10
بس اذا جان اكو نص محدد احنة مسويلة ستايل خاص بي ماراح يتئثر بل 10
-------
break point
هي نقطة تتخلة يم الارقام هاي نقط تخلي ال ديباغ يوكف من يوصللهة //Todo:عبارة عن تعليق يضهر اثناء عمل ديباغ لل تطبيق
----------------
android life cykile
onCreate(), onStart(), onResume(), onPause(), onStop(), and onDestroy()
النضام يعتبر كل وحدة من ذني عبارة عن حالة جديدة من اكتفتي
يعني كل ما يدخل وحدة النضام يعتبرة رح يدخل في اكتفتي جديدة او مرحلة جديدة من الاكتفتي
onCreat():هذه الدالة تشتغل من النضام ينشء الاكتفتي يعني هي اول دالة تشتغل بين دورة حيات الاكتفتي
نستخدمهة علمود نخلي بداية التطبيق بيهة يعني مثلا من يدخل عل تطبيق يطلع مثلا ايقونة تطبيق او اشعار تطبيق او تسجيل دخول
startup يعني ال داخل دالة اون كريت باراميتر اسمة سيف انستانس هذه ال باراميتر من كلاس بندل فايدة ال باراميتر انو يقوم بتخزين حالة الاكتفتي السابقة
وذا الاكتفتي ما شتغلت رح تكون قيمتة null
لما تنتهي مرحلة تنفيذ دالة اون كريت الاكنتفتي رح تدخل بمرحلة ثانية يدخل بدالة اون ستارت وا دالة اون رسيوم
onStart(), onResume()
----
Intent كلاس
يستخدم لل انتقال بين الاكتفتي
مثال
var intent = Intent(this,actvtyname::class.java)
startActivty(intent)
اول باراميتر ياخذ كونتكست الكونتكست رح يكون الكلاس الحالي وثاني باراميتر رح يكون اسم الاكتفتي الي نريد ننتقل الهة ولازم نحدد نوع انو يكون جافا كلاس
وراهة جالة ستارت اكتفتي الي رح تشغل الاكتفتي الي رح ننتقل الهة
اكو طريقة مختصرة
startActivity(Intent(this,actvitynameclass::class.java))
اكو نوعين من الانتينت implicit intent and explicit intent ال explicit intent نخلي التطبيق مالتنة ينتقل من اكتفتي ال اكتفتي داخل التطبيق اما implicit intent تسمح النة نتنقل بين الاكتفتي الخاصة بتطبيقات خارجية مثلا انتنت يفتح الكامرة وا يتلقط صورة انو ستخدمنة تطبيقات خارجية ماكاتبيهة احنة
طبعا نعرف انو ال انتنت يكدر يحمل بيانات ويا نكدر نرسل بيانات عبر اكسترا لاكن اكسترا من اصل 4 اشياء ال 3 البقية هنة action,data,category ال action هو عبارة عن فعل معين تريده ان يحصل مثلا كامرة اتصال ال data يستخدم لتحديد نوع البيانات الي رح يشتغل بي ال action مثلا رقم تلفون صورة الخ
مثال لي استخدام انتنت امبلكت
val m_intent = Intent()
m_intent = setAction(Intent.ACTION._VIEW)
m_intent - setDATA(Uri.parse("https://workingdev.net"))
startActivity(m_intent)
----
تمرير بيانات بين الاكتفتي
كلاس انتنت تكدر تخزن بي بيانات عبر كي فاليو نفس هاش ماب
نستخدم دالة putExtra(key,valeu)
-
شلون نتسقبل البيانات نستدعي خاصية extras
يعني يجيب المعلومات مال مفاتيح ول قيم
مثال
var intentsend = Intent(this,activityname::class.java)
intentsend .putExtra("namekey","value")
startActivty(intentsend)
-
secondactivity
var data = intent.extras
هسة data تخزن بيهة كل قيم المفاتيح شلون نوصل لل قيمة
نوصلله عبر ستخدام المتغير وا ستخدام دالة كيت تاخذ باراميتر المفتاح عبر هذه المفتاح رح نوصل لل قيمة
data.get("name")//نستخدمهة علمود نجيب قيمة نصية
طبعا دوال تختلف علا حسب نوع القيمة
مثلا اذا كان عندنة حرف رح تقول كيتشار
getChar()
-------
ستقبال بيانات من الاكتفتي الي نرسل الهة بيانات
اذا نريج نستقبل بيانات من الاكتفتي رح نسوي اوفرايد الدالة onActivityResult(requestCode:Int,resultCode:Int,data:Intent?){//هذه الدالة تشتغل من نرجع من الاكتفتي
super.onAcctivityResult(requestCode,ResultCode,data)
}
requestCode ال اركيمنت الاول
هو عبارة عن كود انتجر نستخدمة علمود نميز بين الاكتفتي الي نستقبل منهة بيانات
resultCode هذه نخليهة حتة نتئكد انو الانتقال رح يصير يعني البيانات رح تستقبل 3 اركيمنت ال data
هذه نستخدمة علمود نحدد ال ال انتنت الي رح يستقبل البيانات يعني ال رح تتخزن بي
ال اوفرايد لل دالة نسوي داخل الكلاس الي رح ييستقبل البيانات
-
هسة رح يجي دور الاكتفتي الي رح يرجع بيانات
مثال نرجع نص gobackval.setOnClickListener
{
var x = this.intent
x.putExtra("return","hello from second activity")
setResult(Activity.RESULT_OK,x)//هذه الدالة رح نستخدمهة علمود نكول لنضام الاندرويد انو الانتقال جاهز وما بي شي
طبعا الباراميترات الي تاخذهة تاخذ باراميتر لل تئكد من الانتقال ججاهز ام لا وا باراميتر الثامي نخلي بي الانتنت الي رح ينتقل
الباراميتر الاول هوة resultCode finsh()//هذه الدالة تستخدم لل تخلص من الاكتفتيات الي فتحتهة مسبقا يعني المستخدم من يتنقل بين الاكتفتيات من تدخل علا اكتفتي جديدة رح تصير الاكتفتي القديمة جواهة فة يصير ثقل لذالك نستخدم هذه الدالة علمود تغلق جميع الاكتفتيات الجوة
}
-
ملاحضة ال اكتفتي الي رح يستقبل بيانات بداخلة ال ستارت اكتفتي مايدري عن الانتقال رح يصير لذالك رح نستخدم دالة
startActivityForResult(intent,Request_Code)
باراميتر الاول هوة الانتنت الي رح يسقبل بيانات
باراميتر الثاني هوة ال ريكوستكود الي نميز بين الاكتفتيات الي هي اي وحدة رح تستقبل بيانات
-------------
اكو 3 طرق تخزين البيانات
اكو انترنل سيف هو تخزين داخلي داخل الجهاز
اكو اكسترنل سيف هو تخزين خارجي يعني تخزين برام
اكو كلاس شيردبريفنسس هو كلاس نستخدمة علمود نخزن بيانات علا شكل كي و فاليو لاكن هذه ال كي فاليو يتهزن في ملقات اكس ام ل حخزنهة داخل الجاهز الاندرويد وكو طريقة نخزن عبر قاعدة بيانات sqlite نخزن بيانات عبر جداول
وكو طريقة تخزن بيانات عبر الشبكة عبر ريموت داتابيس يعني تكدر تخزن بياناتك مثلا بسيرفر وتكدر تستعيدنهة من تتصل بل شبكة
---
هسة رح اشرح طريقة ال شيردبريفنسس
نضام الاندرويد يجهز فايل شيرد بريفنسس علمود يخزن بي البيانات بفورم او بملف اكس ام ل في مسار data/data/{application package}/share_prefs
االبيانات تنحذف اذا الغينة تثبيت التطبيق او مسحنة البيانات من الضبط
كود جافا class MainActivity : AppCompatActivity() {
private val sherd_pre_file = "sherdprefances"
private var sherpref : SharedPreferences? =null
@SuppressLint("CommitPrefEdits")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
buid.setOnClickListener {
sherpref = getSharedPreferences(sherd_pre_file, 0)
var edit: SharedPreferences.Editor = sherpref!!.edit()
if (!TextUtils.isEmpty(edid.text.toString())) {
var message = edid.text.toString()
edit.putString("message", message)
edit.apply()
edit.commit()
} else {
Toast.makeText(this, "enter somthing", Toast.LENGTH_LONG).show()
}
}
var databack : SharedPreferences = getSharedPreferences(sherd_pre_file,0)
if(databack.contains("message"))
{
var getmessage = databack.getString("message","not found!!")
tuid.text = getmessage
}
}
}
-
xml code
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/edid"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:ems="10"
android:inputType="text"
android:text="Name"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.341" />
<Button
android:id="@+id/buid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="72dp"
android:text="Button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edid" />
<TextView
android:id="@+id/tuid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="76dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/buid"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
دالة apply تخزن البيانات asynchronously يعني خزن البيانات في الخلفية بين ما بعض العمليات تعمل اما دالة commit تخزب ابيانات synchronously يعني خزن البيانات اولا بعدها اكمل باقي العمليات
-------------------------------------------ا
ال كومبونينت content proviedr يستخدم لمشاركة البيانات بين التطبيقات عبر طريقة منضمة وا امنة
---------------------------------------------------------------------------------------------------------------------------------------------------------------
قواعد البانات هو عبارة عن هيكل يسمح لنا بتخزين البيانات بطريقة اكثر ترتيب
يعني يسمح لنا بتخزين البيانات علا شكل جداول الجدول يحتوي علا صفوف وا اعمدة
ااول صف رح نخلي بي الملومات مال الجدول او التعريف لل بيانات الي رح نخليهة يعني مثلا نخلي اسم وا عمر وا رقم وراهة من نريد نضيف بينات تلقائيا رح ينضاف صف جديد ورح يتخلة الاسم جوة الاسم وا العمر جوة العمر وا الرقم حوة الرقم
وا ايضا نكدر ننشئ علاقة بين الجداول علمود نسرع عملية نقل البيانات
database handler يسمح لنا بل تعامل مع الداتا بيس في انشاء الجداول وا انشاء الدوال الي رح نستخدمعهة علمود نتعامل مع قاعدة لبيانات
هذه الكلاس هوة ما موجود بس اجنة ننشئء ونسوي وراثة بستخدام SQLiteOpenHelper
SQLiteOpenHelper class عبارة عن كلاس يستخدم حتة ننشء وا ندير اصدار قاعدة بيانات
علمود نطبق هذه الخواص لازم نطبق الدالتين الي بداخلة onCreate() and onUpgrade() methods
-
SQLiteDatabase class هذه الكلاس بي دوال سنتخدمهة علمود نتعامل مع قواعد البيانات مثل ننشء نحدث نختار نحذف الخ
داخل الدالة اون كريت رح ننشء الجدول مالتنة دالة اون كريت تستدعا مرة وحدة عند انشاء قاعدة البيانات قواعد البيانات مشتركين في مفهوم creat,read,update,dlete
معروف اختصار CRUD
--
writabledatabase يعني قابل لل قرائة وا الكتابة
cursor يسمح النة بقرائة البيانات من الجدول يعني هذه الكلاس يعرف يسوي فيتش من التيبل
------------------ال ال BroadcastReceivers يسمح لبرنامجنا ان تستمع لرسالة محددة من النضام او من برنامج ونكدر نرسل رسائل هم مثلا نرسل ملاحضة البطارية وصلت 10%
--------
ال contentprovuders يسمح النة ان ننشئ برنامج يشارك البيانات بين برامج ثانية يعني يسمح لل برامج الثانوية ان توصل لبيانات التطبيق مالتنة
----------
هذه الكود يعني <action android:name="android.intent.action.MAIN" /> ال اكتفتي هية ال انتري بوينت الي رح يبدي منهة التطبيق بختصار نستخدمة علمود نحدد اي اكتفتي رح تشتغل اول وحدة
------------------------
ال View هم عندة كلاس هذه الكلاس نستخدمة علمود نبرمج ال عناصر ال فيو يعني بي دوال وا خصائص حتة نتحكم بل عناصر ال فيو
---------------
ال Snackbar نفس توست لاكن الاختلاف يضهر بار معين جوة شاشة يطلع بي شي مثلا رابط او اعلان او زر لخ
مثال Snackbar.make(root_layout,"long cliced",Snackbar.LENGTH_LONG).show()
------------------------------
دالة button.setOnLongClickListener ترجع بوليان ترو او فالس
اذا ارجعت ترو يعني الغي كل العمليات وشغل ال اونلونك لسنر يعني اذا جان عدنة اون كلك وا اون لونك لسنر وا ارجعنة ترو يعني من اضل ضاغط الغي ال اونكلك وشغل ال اونلونك لسنر
وذا ارجعت فالس يعني شغل ال اونلونك لسنر بعدها شغل ال اون كلك
---------------
مينيو تستخدم علمود نصل لل اشياء داخل التطبيق بسهولة يعني نتنقل بسهولة موجودة بل زاوية 3 نقاط او 3 خطوط
علمون نتعامل مع المينيو نحتاج ننشء فولدر مينيو داخل مجلد ريسورس بعدها ننشء ملف داخل المجلد الي انشئنا
بعدين نربط ال مينيو بل برنامج مالتنة لازم نسوي اوفرايد لدالة onCreatOptionsMenu داخل مين اكتفتي بعدين نستدعي دالة inflate fuction of menu object
بعدين نضيف حدث لل مينيو حتة نتحكم بل مينيو من المستخدم يضغط نستخدم دالة onOptionsItemSelected كل ايتم داخل المينيو متكون من خاصيتين خاصية android:id="@+id/menufuile" و خاصية android:title="string/menufule"
ال android:id هوة معرف ال ايتم الي رح نضيفة بل مينيو و ال android:title هوة الاسم الي رح يضهر بل مينيو لل ايتم
مثال لي اضافة ايتم داخل مينيو
<item android:id="@+id/menufile"
android:title="@string/menufile"/>
-----------------
----------------------فراكمنت fragment هي عبارة عن قطعة من الاكتفتي نستخدمهة علمود نضيف محتوة معين بدون ما ننتقل لغير اكتفتي
يعني تكدر تعتبرهة شاشة بداخل شاشة يعني مثلا نريد نضغط عل زر معين ماريدة ينتقل لغير اكتفتي بل تبديل المحتوة الموجود عل شاشة ال فراكمنت الهة كلاس بحد وا الهة ملف تصميم بحد وا الهة لايف سايكل بحد وا دوال التفاعل ويهة هم بحد
-
لما تغير توجيه الجهاز يعني تسوي لاندسكيب رح يتم اعادة بناء التطبيق من جديد لذالك لازم تحفض الحالة من تسوي اورنتيشن هذه الحالة تشمل اكتفتي وا فراكمنت
رح نستخدم supportFragmentManager.beginTransaction().apply {
replace(R.id.flfragment,firtfragment)
commit()
}
علمود نحول بين ال فراكمنت بداخلهة نكتب replace(R.id.flfragment,firtfragment)
اول باراميتر هوة ال كونتينر الي نريد نبدلة ثاني باراميتر هوة ال تريد تبدل ال كونتينر بي اذا ما فهمت شوف فيديو https://www.youtube.com/watch?v=-vAI7RSPxOA
الكونتينر افضل شي يكون فريم لياوت ونخليلة اي دي حتة نوصلة
وا لازم نسوي كلاس وا نرث من Fragment()
ونمرر لل كونستركتر ملف ال اكس ام ال الي يحتوي علا التصميم الي نريدة يضهر بل فراكمنت
-------
ال ثريد وا بروسيس
عند تشغيل التطبيق يتم تخصيص موارد لل تطبيق مثل الذاكرة وبعض الاشياء الاخرئ الي يحتاجه التطبيق حتة يوئدي وضيفته تسمة هذه العملية بروسيس
ثريد هو سلسلة من التعليمات المسئولة علا تنفيذ الكود الخاص بنة اذناء ما البرنامج شغال رح ال ثريد يستخدم ال موارد الي حجزهة ال بروسس
الموارد من المحتمل ان تكون قرائة او كتابة من الميموري او دسك وا قرائة من شبكة يعني ال ثريد هو المسئول علا تحديث النصوص الصور التعامل مع رسوميات بل شاشة
ول تعامل مع ادخالات المستخدم هوة المسئول علا تنفيذ كل ذني المهام وا ايضا هوة ال يسوي انفليت لل اكس ام ل وا يحولهم الا فيو يحولهم الا جافا وبجكت مثل الازرار نصوص الخ يفضل ما نسوي حمل كبير علا مين ثريد لن رح يتسبب بثقل التطبيق لذالك اذا جان عدنة مهام كثيرة وا ثقيلة نستخدم ال back ground thread
ال background thread يستخدم لل مهام الطويلة مثل قرائة ول كتابة من شبكات او التخزين يعني يستخدم علمود ما نسوي اي ثقل اعل مين ثريد يعني يكون مستقل عن مين ثريدد
نستخدم ال AsyncTask class للتعامل وا ادارة ال background thread
ال وقت الي ياخذ ال قريد حتة ينفذ مهمة ايطلق عليه threadhold وا ال guidline يعني ترشيحات يفضل اتباعها من اجل عمل سوفتوير او تصميم معين بجودة قوية
-------
مثال حول background htread
اول شي نقوم بي انشاء كلاس يطبق Runnable بعدها نقوم بعمل اوفرايد لل دالة run هذه الدالة نكتب بداخلهة الكود الي نريدة يشتغل بل background بعدها نقوم بي انشاء كائن ثريد وا نمرر له كئن من ruuable الكائن الي رح نمررة بداخلة نسوي اوفرايد لل دالة رن
بعدها نقوم بي استدعاء دالة ستارت مالت ال ثريد
---- دالة runOnUiThread تاخذ هذه الدالة كائن من كلاس Runnabe وتنفذ الكود الخاص بل كلاس رونبل داخل ال مين ثريد
--
كلاس handler يستخدم لي ادارة الثريد وا يستخدم ايضا لل تواصل بين main thread, background thread تذكر المثال من قلنة الكود ما يتنفذ كلة بوقت واحد انو يروح MessageQueue; وراهة ينتضر يتم ختيارة وراهة يتنفذ الهاندلر يسوي هيج انو يختار وراهة ينفذ
------
كلاس AsyncTask هو كلاس يستخدم لتشغيل الكود في الباكرواند هوة يشبه الهاندلر كلاس وا بي خصائص افضل لتحديث ال واجهة المستخدم
اذا تريد تستخدمة لازم تورثة وا تورث الدوال ماتة حتة نستخدمة تورثة انر كلاس او بكلاس ثاني حسب الطريقة الي تريدهة ------
دالة doAsync هية دالة من مكتبة anko تستخدم هذه الدالة لتشغيل background_thread لاكن جميع الاشياء هذه الدالة تفعلاه تلقائيا يعني ما ننشء ثريد وهاي سوالف بل الدالة هية تسوي كلشي تلقائيا يعني مو
مثل كلاس هاندلر او كلاس asynctask اول شي لازم نضيف المكتبة implementation 'org.jetbrains.anko:anko-common:0.10.8'
بل dependencies اما عن طريقة ستخدام الدالة نكتب doAsync{hear write the code well run in the background
activityUiThread {
// make changes to the UI ❷
textView.text = "Hello"
}
}
---------
انوعه الاخطاء في البرنامج --------
تعامل مع تخزين بيانات داخليا انترنل
اول شي رح نستخدم طريقة الكتابة في ملف
اول شي ننشئ كتغير يحوي علا اسم الملف
بعدين ننشء كاءن من دالة openfileoutput هذه الدالة ترجع fileoutputstream تاخذ باراميترات 2 اول واحد اسم الملف ول ثاني ريقة تحديد الوصول لل ملف
بعدها نستخدم الاضافة use هذه الاضافة تقوم بي اغلاق الملف تلقائيا بعد تنفيذ الكود
بعدها رح نقوم بل كتابة بل ملف عبر ستخدام دالة write البيانات الي رح نكتبها بل ملف رح نحولها الا مصفوفة نوعها بايت
val filename = "ourfile"
val out = openFIleOutput(ourfile,Context.MODE_PRIVATE)
out.use{
out.write(txtidexample.text.toString().toByteArray())
}
هذه طريقة انشاء ملف وا الكتابة فيه اما لالن رح اشرح طريقة القرائة في ملف
اول ننشء متغير يحتوي لا اسم الملف الي نريد نقرة منة
بعدين ننشء كائن من openFileInput() هذه ترجع كائن نوعة fileinputstream تاخذ باراميتر نوعة ملف الي رح نقرة من البيانات
بعدين نستخدم الاضافة use بداخلهة رح ننشء كائن نوعة StringBuilder() حتة نجمع النصوص الي رح نقرائه بداخلة
وراهة نقوم بل قرائة من الملف بستخدام دالة read الي رح نستخدمهة من الكائن openFIleINput هذه دالة ترجع نوع انتجر رقم ال اسكي لل حرف لذالك الرقم لازم نخزنة في متغير
وراهة رح نسوي لوب هذه الوب رح يكون بداخلهة شرط رح تلف علا الملف الي نقرة منة تقارن المتغير الي بداخلة مخزنين رقم الاسكي مال الحرف اذا جان لا يساوي =! ستمر بل لف عل ملف وقرة بيانات
داخل الوب رح نضيف ال حرف الي قرينا لل كائن الي انشئنا من ش=stringbuilder ونحولة الا نوع بيانات ْchar وراهة رح نقرة من الملف اذا ما لكة شي اخرج من لوب وا طبعلنة الملف عبرة الكائن الي خنة بي البيانات مثال لل كود
val filename = "ourfile.txt"
val input = openFileInput(filename) ➊
input.use {
var buffer = StringBuilder() ➋
var bytes_read = input.read() ➌
while(bytes_read != -1) { ➍
buffer.append(bytes_read.toChar()) ➎
bytes_read = input.read() ➏
}
println(buffer.toString()) ➐
}
---------ؤ
شرح هذه الكود class.java.name::
ال :: تستخدم حتة يعطيني مرحع لشيء معين مثلا دالة او خاصية كائن كلاس الخ ال class يعطينا معلومات حول الكلاس الي نستخدمة ال .java هو يرجع النة كائن هذه الكائن مرتبط بكائن كوتلن ليش لن المعلومات الي رح يعطينياها مثل دوال خصائص مكتوبة بجافا لذالك نريد مرجع مرتبط بكائن جافا حتة نكدر نستخدمة بكود الكولتن
ال .name هية خاصية نستخدمهة علمود تعطينا اسم الكلاس
----------------------------
brodcastreciver
هو عبارة عن كومبونت يستخدم لي ارسال وا ستقبال رسائل النضام مثلا المستخدم ضغط علا شعار او البطارية انخفضت او قام بي اتصال السماعة الخ
هناك نوعين من هذه الكومبونت
هو system brodcast هو رسائل من النضام
custom brodcast هو رسائل ترسل بستخدام تطبيقنا او تطبيقات ثانية
اذا تريد تتتعامل مع الرسالة يعني نردهة لازم نسجل reciver
اكو طريقتين نسجل بيهة رسيفر عبر
manifest / context
مثال حول تسجيل رسيفر في ملف manifest
<receiver ➊ // هذه النود نستخدمهة علمود نعرف ال رسيفر android:name=".MyReceiver" ➋//هذه اسم الكلاس الرسيفر الي رح يرث من كلاس برودكاست رسيفر android:enabled="true"
android:exported="true">
<intent-filter> ➌// هنا نحدد النوع الرسائل الي رح يتعامل معها الرسيفر
<action android:name="com.workingdev.DOSOMETHING"/>
</intent-filter>
</receiver>
طريقة تسجيل ريسيفر في الكونتيكت
val receiver = MyReceiver()//هنا انشئنا كائن من كلاس ما رسيفر الييرث من برودكاست رسيفر هذه الكائن رح يكون هوة المستلم لل رسالة
val intentFilter = IntentFilter("com.example.MY_ACTION")هذه الكائن من انتنت فلتر هوة ال كائن الي يمسك الرسالة الي نريد نتعامل وياهة registerReceiver(receiver, intentFilter) هذه الدالة هية المستمع لل رسالة تاخذ باراميترين اول واحد هوة المستلم الرسيفر ول ثاني باراميتر هوة نوع الرسالة الي يتعامل بيهة الرسيفر
يعني هذه الدالة رح نحدد بيهة الرسيفر الي رح يستلم الرسالة ول رسالة الي رح يتعامل وياهة يعني تسجل الرسيفر المحدد الي رح يتعامل وية الرسالة
class MyReceiver : BroadcastReceiver() {//هذه الكلاس الي رح نرث منة حتة نستخدم الرسيفر
override fun onReceive(context: Context?, intent: Intent?)//هذه الدالة يتم استدعائها عندما يستلم الرسيفر رسالة فايدة هذه الدالة انو نخلي الكود الي الي رح يتعامل وية النوع المحدد مال الرسالة {
if (intent?.action == "com.example.MY_ACTION") {//هذه شرط نستخدمة لل تئكد من نوع الرسالة الي رح نتعامل ويا
// handle the broadcast message here
val message = intent.getStringExtra("message")
Log.d("MyReceiver", "Received message: $message")
}
}
}
يمكن استلام برودكاست حتة لو كان التطبيق يعمل في الخلفية يعني اذا خلينا سجلنة رسيفر بل مينفيست فايل
ال رسيفر رح يتسجل تلقائيا بواسطة نضام الاندرويد من يتثبت التطبيق
يعني احنة بس نعرفة بل مينفيست فايل ول اندرويد رح يسجلة تلقائيبا من يتثبت التطبيق
ويبقة يسجل رسايل حتة لو لغة من الخلفية طيب ليش
لن ال مينفيست فايل مرتبط بل بكج مال تطبيق مالتنة اكو بعض التحفضات انو ال مينفيست مايكدر يستلم انو اذا النضام داخل بحالة
sellp or procsses kiled by the system the fix is to restart the system or device wek up from the system
-
خطوات انشاء برودكاست ريسيفر
اول شي تحدد البرودكاست الي تريد تتعامل ويا مثلا سستم برودكات وا كوستم برودكاست
كوستم برودكاست هنة رسايل تطبيقك يرسلهة للتواصل معك او للتواصل مع تطبيقات ثانية تكدر انت تحدد
نوع الرسالة الي رح يرسلهة اما سستم برودكاست هنة رسالة يرسلهة النضام
ثاني شي نحدد طريقة تسجيل الرسيفر عبر كونتيكست او عبر مينفس فايل
الفرق بين الكونتيكست وا مينفيست انو الكونتيكس يستلم برودكاست اثناء تشغيل التطبيق من التطبيق ينغلق بعد ما يستلم
اما اذا عرفت بل مينفيست انو رح يتسجل تلقائيا بواسطة نضام الاندرويد وا يبقة يستلم برودكاست حتة لو التطبيق ما يشتغل
ثالث شي ننشء كلاس يرث من برودكاست رسيفر
رابع شي نسوي اوفرايد لل دالة اونرسيفر حتة نعالج الاكشن الي يجي
اكو بعض ال برودكاست ما تكدر تتعامل معهم في المينفست فايل
---
فرق بين امبلكت برودكاست وا يكسبلكت برودكاست
explicit brodcast هو ارسال برودكاست لي اكتفتي معين او تطبيق معين
implicit brodcast هو ارسال رسالة بشكل عام يعني اي تطبيق يستطيع ان يرد علا البرودكاست
-----
view binding هي طريقة لل وصول لعناصر ال اكسامال بطريقة اسهل
مثال class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
ال كلاس بداية اسمة لازم نفس اسم ملف ال اكس ام ال حتة نسويلة انفليت
ال binding root هو يمثل جميع عناصر ال فيو يعني بختصار viewgroup
Android Data Binding library هذه المكتبة هية الي رح تسويلنة الكلاس تلقائيا
الكلاس رح يكون اسمة علا نفس اسم ملف ال اكس ام ل من رح نفعل ال data binding
اندرويد ستوديو رح ينشء كلاس تلقائيا لكل ملف اكس ام ال يكون بنفس اسم ملف ال اكس ام ال
لذالك من تريد تستخدم ال داتا بايدنك رح نكتبة نفس اسم الملف ال اكس ام ال
----------------------
service
هي مجموعة من الكومبونت تشتغل بدون يوزر انترفيس او واجهة مستخدم
هناك نوعين من الخدمات خدمات forground service and background service
----------------
support muiltpy screan
تكدر تخلي التصميم عب كونسترينت لايوات او تكدر تخلي لكل ملف اكس ام ال لنوعية شاشة معينة
مجرد تنسخ التصميم مثال --------------------------------
activity stack
تكدر تتخيلة انو عبارة عن كوب وعندك 3 اكتفتيات
اكتفتي a,b,c
اذا انتقلت من اكتفتي a
b الا اكتفتي
b رح يكون اكتفتي a رح يكون فوق b وذا انتقلت من اكتفتي
c الا اكتفتي c رح يكون ال اكتفتي
b فوق اكتفتي
c وذا رجعت من اكتفتي رح تنحذف ال اكتفتي يعني تنحذف من الكوب
ورح تكون ال اكتفتي ال رجع الهة هية الحالية او الاكتفتي الاعلا
finish() هذه الدالة رح تمسح الاكتفتي من الاكتفتي ستاك يعني تمسح الاكتفي الحالية
--------------------
اذنوات تستخدمهة ملف ال مينفيست تكتب
<uses-permission android:name=""/>
نحتاج 3 دوال ثنين احنة ننشئهن وحدة نسويلهة اوفرايد
الدالة الاولا نستخدمهة علمود نتئكد من البيرمشن الدالة الثاني نستخدمهة علمود نطلب بيرمشن من اليوزر
الدالة الثالثة نسويلهة اوفرايد نستخدهة علمود نسوي هاندل لل بيرمشن اذا نقبل
كود تعامل مع اذن الانترنت private fun permissiontest() = ActivityCompat.checkSelfPermission(this,Manifest.permission.INTERNET) == PackageManager.PERMISSION_GRANTED//هذه الدالة تشيك علا الاذن موجود ام لا اذا موجود ترجع ترو اذا لا ترجع فالس
private fun requestpermission(){//هذه الدالة تستخدم لي طلب بيرمشن من الممستخدم وا تقوم بي اضافة الاذناوات في لست وا تشيك اذا كان الاذن موجود تطلبة وذا جان ما موجود تضيفة بل لستة
var permissionarry=mutableListOf<String>()
if(!permissiontest()){
permissionarry.add(Manifest.permission.INTERNET)
}
if(permissionarry.isNotEmpty()){
ActivityCompat.requestPermissions(this,permissionarry.toTypedArray(),0)
}
}
override fun onRequestPermissionsResult(//هذه الدالة تستخدم لي تعامل البيرمشن اذا تم الموافقة عليه
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if(requestCode ==0 && grantResults.isNotEmpty()){
for(i in grantResults.indices){
if(grantResults[i] == PackageManager.PERMISSION_GRANTED){
Log.d("permissionsrequest","${permissions[i]}.granted")
}
}
}
}
--------------------------------
impilicit intent
يعني فتح اكتفتي جديدة لاكن خارجية يعني نستخدم اكتفتيات مال تطبيقات خارجية
مثال لكي نختار صورة من الاستديو
val imgpicker = registerForActivityResult(ActivityResultContracts.GetContent()){result :Uri?->
if(result!=null){
binding.img.setImageURI(result)//result يمثل النتائج ال راجعة من الاكتفتي }
}
binding.button.setOnClickListener {
Intent(Intent.ACTION_GET_CONTENT).also {
it.type = "image/*"
imgpicker.launch(it.toString())
}
}
-----
uri هوة رابط او مسار ال بيانات
يعني مقلا رابط الفيس رح يكون facebook.com
اما uri
هوة رابط البيانات الداخلية مثلا رابط المسار مال ملف معين مثلا
c://foled/data/image
-------
toolbar menus هي الايقونات الي تنضاف في لمربع طريقة لانشاء
اول شي ننئش مجلد يحتوي علا ملف التصميم هذه الملف رح يحتوي علا المينيو داخله رح نخلي كل العناصر الي نريدهة تضهر بل مينيو
وراهة نضيف ال يقونات بمجلد ال دراوبل الايقونات الي نريد نستخدمهة
وراهة نروح علا مجلد دراوبل نضغط كلك ايمن ونختار
image asset
ونختار الايقونة
هسة رح نضيفهم بل مينيو عبر تاغ الايتم
<item
android:id="@+id/imsetting"//هنا نحدد الايدي لل ايقونة حتة نبرمجهة
android:title="setting"//هوة اسم او عنوان الايقونة
android:icon="@drawable/ic_setting"//هنا مسار الايقونة app:showAsAction="ifRoom"/>//هنا طريقة ضهور الايقونة هنا نكلة خلي الايقونة تضهر وتكون قابلة لل ضغط وذا ماكو مساحة خلي الايقونة بل اوفر فلوة
بعدها نروح عل اكتفتي ونروح نطبق المينيو الي نريدهة تضهر بل بار
override fun onCreateOptionsMenu(menu: Menu?): Boolean {//هذه الدالة نستخدمهة علمود ننشئ المينيو وا نسويلهة انفليت لل عناصر
menuInflater.inflate(R.menu.app_bar_menu,menu)//هنا سوينة انفليت لل مينيو return true//هنا ارجعنة ترو يعني ال مينيو تم انشائها بنجاح
الباراميتر مينيو هذه يمثل المينيو الي انشئناها
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {//هنا سوينة اوفرايد لهذه الدالة هذه نستخدمهة علمود نبرمج الايقونات
when(item.itemId){
R.id.imsetting -> Toast.makeText(this,"you have clicked setting",Toast.LENGTH_SHORT).show()
R.id.imfavorit -> Toast.makeText(this,"you have clicked favirot",Toast.LENGTH_SHORT).show()
R.id.imaddcontact -> Toast.makeText(this,"you have clicked add contact",Toast.LENGTH_SHORT).show()
R.id.imcloseapp->Toast.makeText(this,"you have be clicked closed app",Toast.LENGTH_SHORT).show()
R.id.imfeesback->Toast.makeText(this,"you have be clicked feedback",Toast.LENGTH_SHORT).show()
}
return true
}
---------------
alert dailog نستخدمهة علمود نضهر لل مستخدم تنبيه معين نستخدم كلاس val addcontactdilog = AlertDialog.Builder(this).//هذه الكلاس رح نستخدمة علمود ننشء ال دايالوك
setTitle("add persion cotact")//هذه الدالة تستخدم علمود تخلي تايتل لل دايالوك الي يضهر
.setMessage("do you want to add persion contact")//هذه الدالة تستخدم علمود تضهر رسالة مال دايالوك
.setIcon(R.drawable.ic_add_contact_foreground)//هذه الدالة تستخدم علمود تضهر ايقونة بل دايالوك
.setPositiveButton("yes"){dialogInterface,i->//هذه دالة تنشء زر لل موافقة علا شيء معين بيهة لامبدة اكسبرشن تاخذ باراميترين اول واحد يمثل ال دايالوك الي رح يضهر لل مستخدم اما ثاني باراميتر يمثل الزر المضغوط
Toast.makeText(this,"you better thin bad stuff add",Toast.LENGTH_SHORT).show()
}
.setNegativeButton("no"){dialogInterface,i->//هذه الدالة تنشء زر يستخدم لرفض الاشياء بيهة لامبدة اكسبرشن تاخذ باراميترين اول واحد يمثل ال دايالوك الي رح يضهر لل مستخدم اما ثاني باراميتر يمثل الزر المضغوط
Toast.makeText(this,"no dont back regicted",Toast.LENGTH_SHORT).show()
}.creat()//هذه الدالة رح تنشء ال دايالوك لن هسة هذه كلة الكتبنا يكون بولدر يعني من كلاس بولدر مجرد بنينا ما انشئنا لذالك نستخدم هذه الدالة حتة ننشئة
هذه الدايالوك يستخدم علمود نضهر لل مستخدم موافقة علا شيء محدد مثلا اضافة المستخدم توافق ام ترفض
هسة رح اشرح دايالوك يضهر اكثر من اختيار طبعا كلشي نفس الخطوات لاكن الاختلاف الدالة
var options = arrayOf("stoic life","losser life","stoic and bain life")
val singlechoicedialog = AlertDialog.Builder(this)
.setTitle("choise option")
.setSingleChoiceItems(options,0){dialogInterface,i->
Toast.makeText(this,"you have choice $options[i]",Toast.LENGTH_SHORT).show()
}
.setPositiveButton("accspted"){_,_->
Toast.makeText(this,"you better thin bad stuff add",Toast.LENGTH_SHORT).show()
}
.setNegativeButton("decline"){_,_->
Toast.makeText(this,"no dont back regicted",Toast.LENGTH_SHORT).show()
}.create()
اكو طريقة ثالثة علمود نضهر دايالوك انو نسوي اكثر من خيار يختار المستخدم
نفس المثال الفوك لاكن اختلاف الدالة
var options = arrayOf("stoic life","losser life","stoic and bain life")
val multichoice= AlertDialog.Builder(this)
.setTitle("choise option")
.setMultiChoiceItems(options, booleanArrayOf(false,true,false)){ _, i, ischecked->//ischeked لام نختار ال شيك بوكس وا نسوي عليه صح رح يكون هذه الباراميتر ترو وذا شلنة الصح رح يكون فالس if (ischecked)
Toast.makeText(this,"is cheked $options[i]",Toast.LENGTH_SHORT).show()
else{
Toast.makeText(this,"unchecked $options[i]",Toast.LENGTH_SHORT).show()
}
.setPositiveButton("accspted"){_,_->
Toast.makeText(this,"you better thin bad stuff add",Toast.LENGTH_SHORT).show()
}
.setNegativeButton("decline"){_,_->
Toast.makeText(this,"no dont back regicted",Toast.LENGTH_SHORT).show()
}.create()
----------------
spinner شايف من تريد تنشئ يميل ويطلعلك لستة بيهة مجموعة قيم مثلا اشهر السنة او البلاد او مفتاح الدول هوة هذه السبنر
نستخدم عنصر سبنر اول شي نسوي نضيف القيم بمصفوفة نصية بملف النصوص
بعدين نضيف القيم بل عنصر اكس ام ال بعدين نجي نبرمجة بل كود نكدر نخلي من يختار المستخدم قيمة معينة بل لستة نسوي شي معين <Spinner
android:id="@+id/spmonths"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginTop="72dp"
android:entries="@array/months"//هذه مسار القيم app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btndilog3" />
هسة رح نجي عل كود
binding.spmonths.onItemSelectedListener = object: AdapterView.OnItemSelectedListener{
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
}
هنا نسوي فعل معين من المستخدم يختار احد القيم من لستة
باراميتر الاول هوة يمثل السبنر باراميتر الثاني يمثل القيمة المختارة باراميتر الثالث يمثل مكان القيمة باراميتر ال رابع يمثل القيمة الرايعة
override fun onNothingSelected(parent: AdapterView<*>?) {
}
}
}
-------------------
bottom nagigation هو عبارة عن ازرار تستخدم لل تنقل بين الفراكمنت
مانكدر نستخدمة لازم نضيفة بل دبندسيز لنة مضيوف بل مكتبة مال ميتيريل ديزاين
implementation 'com.google.android.material:material:1.5.0'
وراهة ننشئ مينيو رح نخلي بيهة الايقونات الي نريدهة تضهر بل نافكيشن بوتوم
هذه كود ال اكس ام ال <com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/buttomnavifationbar"
android:layout_width="wrap_content"
android:layout_height="75dp"
app:menu="@menu/buttom_nav_menu" />//هنا وصلنة لملف ال مينيو الي نريد نخلي بي الايقونات
طبعا يستخدم لل تنقل بين ال فراكمنت شوف هذه الفيديو اذا ما فهمت
https://www.youtube.com/watch?v=AL_1UDa9l3U&list=PLQkwcJG4YTCTq1raTb5iMuxnEB06J1VHX&index=23
---------
viewpager 2
تكدر تعتبرة هوة ريسايكل فيو لاكن بل عرض
اول شي نضيف مكتبة implementation 'com.google.android.material:material:1.5.0'
بعدين نضيف ال فيوبيجر بل اكس امل ال
<androidx.viewpager2.widget.ViewPager2
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
بعدين ننشء ملف اكس ام ال يكون التصميم مال الا فيو بيجر
-----
tab layout viewpager 2
يستخدم لل تنقل بين النوافذ
اول شي لازم طبق مكتبة ال ميتيريال ديزاين ثاني شي تضيفة بل اكس ام ال
<com.google.android.material.tabs.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
وراهة نطبقة بل كود البقرمجي
TabLayoutMediator(binding.tablayout,binding.viewpager){tab,position->//هنا ستدعينة هذه الكلاس حتة نربط التاب بل فيو بيجر اول باراميتر هوة التاب لياوت وا ثاني باراميتر هوة الفيوبيجر وا الباراميتر الاول يمثل التاب بل لمبدة اكسبرشن وثاني بااميتر يمثل مكان التاب
tab.text = "tab${position +1}"//هنا خلينة النص لل تاب وا خلينة مكانة
}.attach()//هذه الدالة تعني اربط التاب بل فيوبيجر
binding.tablayout.addOnTabSelectedListener(object:TabLayout.OnTabSelectedListener{//هنا رح نستخدم انونيموس كلاس يطبق انترفيس اونتاب سيليكتيد لستنير حتة نبرمج التاب اذا شخص ضغط عليهن
override fun onTabSelected(tab: TabLayout.Tab?) {
Toast.makeText(this@MainActivity,"you have selected tab",Toast.LENGTH_SHORT).show()//هذه الدالة تستخدمه اذا تريد تبرمج الزر عند ضغط عليه
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
Toast.makeText(this@MainActivity,"you have unselected ${tab?.position.toString()}",Toast.LENGTH_SHORT).show()هذه الدالة تستخدم ختة تبرمج الزر اذا ضغطت علا غير زر
}
override fun onTabReselected(tab: TabLayout.Tab?) {
Toast.makeText(this@MainActivity,"you have resalcted ${tab?.position.toString()}",Toast.LENGTH_SHORT).show()هذه الدالة تستخدم لتبرمج زر اذا انضغط عليه مرة ثانية
}
})
-------
slidable menu هية مينيو من تضغط عليهة تطلع بل زاوية كود اكس ام ال
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/drawer"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tvtext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text view"
android:textSize="40sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/navid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:headerLayout="@layout/header"
app:menu="@menu/buttom_nav_menu"
android:layout_gravity="start"
android:fitsSystemWindows="true"/>
</androidx.drawerlayout.widget.DrawerLayout>
كود برمجي
lateinit var toggel :ActionBarDrawerToggle//هنا عرفنة ال توكل بتن الي هوة ال 3 نقاط الي تكون بل زاوية مال مينيو
toggel = ActionBarDrawerToggle(this,binding.drawer,R.string.open,R.string.closed)//هنا مهدنة قيمتة نطينا ال كونتيكست وا نطينا ال نافكيشن دراور الي رح يطلع بي وا عطينا نصين هذني النصوص يطلعن لل اشناص العميان
binding.drawer.addDrawerListener(toggel)//هنا ضفنة ال 3 نقاط بل نافكيشن دراور
toggel.syncState()//هنا كنكنة ال 3 نقاط بل نافكيشن دراور
supportActionBar?.setDisplayHomeAsUpEnabled(true) //هذه الكود رح يسمحلنة بل وصول لل اكشن بار مال الاكتفتي الحالية وا يفعل زر الرجوع
binding.navid.setNavigationItemSelectedListener {//هنا نبرمج الازرار الي رح تنضغط بل مينيو
when(it.itemId){
R.id.imhome -> Toast.makeText(applicationContext,"you clicked1",Toast.LENGTH_SHORT).show()
R.id.improfile -> Toast.makeText(applicationContext,"you clicked2",Toast.LENGTH_SHORT).show()
}
true
}
fun onOptionsItemSelected(item: MenuItem): Boolean {
if(toggel.onOptionsItemSelected(item)){
return true
}
return super.onOptionsItemSelected(item)
}
}}
-------
notifacdtion ارسال اشعارات لل مستخدمين حول شيء معين
first thing we nead to open NOTIFICATIONS channel that used to hold NOTIFICATIONS confugration
val channel_id = "channelid"//هذه اي دي قناة الاشعارات
val channel_name = "channelname"//هذه اسم قناة الاشعارات
val notfi_id = 0
creatNotificationChannel()
val notification = NotificationCompat.Builder(this, channel_id)
.setContentTitle("am the title")
.setContentText("am text")
.setSmallIcon(R.drawable.ic_add_contact_foreground)
.setPriority(NotificationCompat.PRIORITY_LOW)
.build()
val notificationmanager = NotificationManagerCompat.from(this)
binding.showbtn.setOnClickListener {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
}
notificationmanager.notify(notfi_id,notification)
}
}
fun creatNotificationChannel(){//هذه دالة احنة نسويهة حتة ننشئ قناة
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){//هنا نتئكد اذا اصدار اس دي كي اعلة او يساوي اصدار اوريو
val channel = NotificationChannel(channel_id, channel_name,NotificationManager.
IMPORTANCE_DEFAULT).apply {
lightColor = Color.GREEN
enableLights(true)
}//هنا مهدنة القناة يعني سوينة اعداداتهة وا اعطيناها اي دي القناة وا اسم القناة وا افضلية الاشعارات الي نريد نستخدمهة وا دالة ابلاي تستخدم لفعل شيء معين عند حدوث الاشعار
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(channel)
}
}
-------------
intent service or jobintentservice
هوة سب كلاس من كلاس يرفرس هذه الكلاس يوفر النة طرق تعامل مع عمليات اسايكروناز يعني نسوي اكثر من عملية بل خلفية بدون ما نسوي بلوك لل مين ثريد
اول شي لازم لكل سيرفس ننشء كلاس
class MyIntentServace : JobIntentService() {
companion object{
fun enqueueWork(context: Context, intent:Intent){//هذه الدالة الي رح نستدعيهة نمرر الهة ال كونتيكست وا ال انتنت الي هوة يمثل السيرفس الي رح يشتغل بل باكراوند
enqueueWork(context,MyIntentServace::class.java,0,intent)//هذه الدالة هية الي رح تخليلنة ال المهام بقائمة نمرر الهة الكونتيكست وا ال كلاس او الاكتفتي الي رح يشتغل بيهة المهمة وا نمرر الهة كود حتة نميز بين الخدمات وا نمرر الهة ال انتنت الي هوة المهمة
}
}
override fun onHandleWork(intent: Intent) {//هذه الدالة رح تعالج السيرفس الي رح تجي من القائمة يعني تعالج ال مهمة الي نريدهة تشتغل بل خلفية
}
}
من نستدعي الدالة enqueueWork(context,intent)
وا نمرر الكونتيكس وا المهمة او الانتنت رح تلقائيا كلاس
jobintentservice call the onhandlejob to handle the task and run start service
----------
services هو كومبونت يستخدم لتشغيل مهام في الخلفية لمدة طويلة حتة لو ما تحتاج تفاعل وا ايضا يستخدم لعمل مهام حتة لو التطبيق ما مشتغل وا ضاهر لل مستخدم
اكو انواع من السيرفس
1:started service هي عبارة عن اتصال داخلي يبدء من دالة startservice() يستخدم هذه الاتصال لكي يقوم بعملية اما تكمل كلها او تتوقف من قبل المستخدم او عبر قطع الاتصال
مثل تحميل او تشغيل اغاني او تشغيل فيديو الخ
2:bound service:يسمح لي كومبونت ثانوين مثل اكتفتيس بل ربط وا تواصل مع السيرفسس عبر انترفيس يعني يفتح علاقة بين الكلاينت وا الخدمات
bindservice()هذه الدالة تاخذ انتنت ال انتنت هوة ال تفاصيل مال السيرفسس وا ترجع ترو او فالس
اذا ارجعت ترو رح ترجع كائن
serviceconnection
هذه الكائن يستخدم لل تحكم بل اتصال بين الكومبونت وا السيرفسس
بي دالتين دالة الاولا تستخدم لمعالجة الاتصال
onserviceconnected()
وا دالة الثانية لمعالجة الاتصال اذا توقف
اسم الدالة
onservicedisconnected()
-
onStartCommand()
Download