بناء تطبيق بلوجر و الاستعانة ب recyclerView من خلال الكوتلن

 قبل مدة ليست بالبعيدة لتستطيع جلب نص JSON من الانترنيت ثم نقله الى دالة تقوم باستخراج المعلومات المطلوبة منه ثم الحاقها ب Data class ومنه الى   Adapter  كان يجب ان تكون محترفا و لمكتبات مساعدة او نقل و لصق لمجموعة من الاكواد دون فهمها لكن الان مع كوتلن اصبح الامر اسهل و دون حاجة الى مكتبات هذا ما سنراه في هذه التدوينة .

هي نفس المراحل لكن باسلوب ابسط ولكي تفهم اكثر لدينا Api الخاص باحدى مدوناتي التجريبة على بلوجر .
ما نرغب به هو استخراج عنوان  و محتوى و صورة التدوينة لهذا سنحتاج الى مكتبة Picasso .
لهذا اضف حقنة المكتبة من خلال ملف  build.gradle :

dependencies {
    //....
    implementation 'com.squareup.picasso:picasso:2.5.2'
}


بلوجر feed
ان كنت تستعمل جوجل كروم سيظهر JSON بطريقة غير مرتبة لذا حاول ايجاد اضافة تساعد على قراءة JSON
feed: JSONObject
   entry: JSONArray
 
     title: JSONObject
           $t
     content: JSONObject
           $t
     media$thumbnail:  JSONObject
           url 
اما على الاندرويد ستوديو فاليك الملفات التي ساستعين بها: 5 ملفات فقط

نقوم بانشاء ملفات Xml :
في الملف الرئيسي : سنضع recyclerView مع button لجلب باقي التدوينات و ProgressBar لاظهار شريط عند جلب البيانات.


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:id="@+id/hostLayout"
                android:layout_width="match_parent"
                android:background="#e7e6e6"
                android:layout_height="match_parent">

    <ProgressBar
        android:id="@+id/pBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="-7dp"
        android:indeterminate="true"
        />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_margin="10dp"
        app:backgroundTint="#fff"
        app:elevation="20dp"
        app:srcCompat="@mipmap/ic_launcher"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/items"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/pBar"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"/>
</RelativeLayout>

ثم قم بانشاء ملف xml ليكون الذي ستظهر فيه التدوينات ببساطة فيه مكان للصورة و العنوان و محتوى التدوينة :
right click on layout => New =>LayoutRecourceFile=> name=> ok


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:orientation="vertical"
                android:layout_margin="20px"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/thumb"
        android:layout_width="match_parent"
        android:layout_height="190dp"/>

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10px"
        android:padding="5px"
        android:textSize="20dp"
        android:background="@color/colorPrimaryDark"
        android:textColor="@android:color/white"/>

    <TextView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="40dp"
        android:textSize="20dp"
        android:padding="2px"
        android:background="@android:color/white"
        android:layout_alignBottom="@+id/thumb"/>
</RelativeLayout>

نتقل الان الى ملفات الكوتلن :
قبل كل شيء نقوم بانشاء ملف dataClass يستقبل ثلاث متغيرات title content imgUrl

data class Posts(
        var title: String? = null,
        var content: String? = null,
        var imgUrl: String? = null

)


اولا سنقوم باضافة كلاس اسمه mAdapter
right Click app => New => kotlin Class/File => name :mAdapter =>ok

class mAdapter(var lists: List) : RecyclerView.Adapter() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
            Item( LayoutInflater.from(parent.context).inflate(R.layout.list_layout, parent, false))
    override fun getItemCount() = lists.size
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) =(holder as Item).bindData(lists[position])

    class Item(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bindData(post: Posts) {
            //عنوان التدوينة
            itemView.title.text = post.title
            // ارجاع جزء من التدوينة بعد تحويلها الى نص عادي
            itemView.content.text = TextUtils.substring(Html.fromHtml(post.content),0,50)
            if(!post.imgUrl.isNullOrEmpty()){
                //تحميل الصورة باستعمال مكتبة بكاسو
                Picasso.with(itemView.context).load(post.imgUrl)
                        .fit().into(itemView.thumb)
            }
        }
    }
}

لم يتبقى الكثير الان اذهب الى الملف الرئيسي
في هذا الملف سنجلب JSON من الويب على شكل string ثم نقوم باستخراج المعلومات التي نرغب بها بعد ذلك نحيل المعلومات الى adapter ليضعها في recyclerView .

class Main : AppCompatActivity() {

    internal var json = ""
    internal lateinit var lista: ArrayList
    lateinit var  adapter:mAdapter
    var perPage:Int=11

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.ac_main)
        lista= ArrayList()
        items.layoutManager = LinearLayoutManager(this)
        adapter=mAdapter(lista)
        items.adapter = adapter
        // جلب البيانات في الخلفية دن اية عرقلة
        //الرابط به 10 تدوينات كحد اقصى
        GetJson().execute("http://www.androdihow.blogspot.com/feeds/posts/default?alt=json&max-results=10")
        //عند الظغط على هذا الزر سيتم تحميل المزيد من التدوينات
        fab.setOnClickListener {
            // الرابط به عشر تدوينات كحد اقصى و نقطة البدأ
            GetJson().execute("http://www.androdihow.blogspot.com/feeds/posts/default?alt=json&max-results=10&start-index=$perPage")
            perPage+=10
        }
    }
    private inner class GetJson : AsyncTask < String, Int, String > () {
        override fun onPreExecute() {
            super.onPreExecute()
            // اضهار الشريط
            pBar.visibility= View.VISIBLE
        }

        override fun doInBackground(vararg urls: String): String {
            try {
                return URL(urls[0]).readText()
            }catch (e:Exception){
                return ""
            }

        }


        override fun onPostExecute(result: String) {
            if (!result.isNullOrEmpty()) {
                json = result
                parseJSON(json)
            }else{
            //عدم وجود انترنيت
            //مشكلة في api
            }
        }
    }

    fun parseJSON(json: String) {
        try{
            val jsonObj = JSONObject(json)
            // الوصول الى feed
            val feed = jsonObj.getJSONObject("feed")
            //جعل الاونتري مثل array
            val posts = feed.getJSONArray("entry")
            // عمل لوب على كل التدوينات
            for (i in 0..posts.length()-1) {
                val post = Posts()
                val p=posts.getJSONObject(i)
                //عنوان التدوينة
                val title=p.getJSONObject("title").getString("\$t")
                //محتوى التدوينة
                val content=p.getJSONObject("content").getString("\$t")
                //صورة التدوينة
                val img=p.getJSONObject("media\$thumbnail").getString("url").replace("/s72-c","")
                //حفظ البيانات في dataclass
                post.title=title
                post.content=content
                post.imgUrl=img
                // اضافة التدوينة الى القائمة
                lista.add(post)
                //لوب من جديد
            }
            //اعلام بان هناك تدوينات جديدة
            adapter.notifyItemInserted(lista.size-1)
        }catch (ex:Exception){
            //في حالة وجود خطا
            Log.e("erorr",ex.message.toString())
            val snackbar = Snackbar
                    .make(hostLayout, "يوجد شيء مريب حاول مجددا", Snackbar.LENGTH_INDEFINITE)
                    .setAction("Refresh", View.OnClickListener {
                        GetJson()
                                .execute("http://www.androdihow.blogspot.com/feeds/posts/default?alt=json")
                    })
            snackbar.show()
        }
        //ايقاف الشريط
        pBar.visibility= View.GONE
    }
}


و نكون بهذا قد انتهينا من احد التطبيقات التي سعدتنا كوتلن فيها بقوة و ترقبوا تطبيق مفتح المصدر منا باذن الله .


هل ترغب في مثل هذه التدوينات

اسماعيل ايت بلا

ببساطة ارغب في تجربة جديدة من التعلم من خلال مشاركة ما تعلمه يجبرني ذلك على البحث لمدة طويلة مما يجعل الموقع جديرا بالثقة

اترك لنا تعليقا

الاشتراك بالقائمة البريدية

توصل باحدث مواضيعنا و كن على اطلاع باخر اخبار وتقنيات الاندرويد