ทำไม เพจ MikkiPastel และเพจอื่น ๆ ถึงใช้ . ระหว่างบรรทัด มาอธิบายด้วย coding กัน

Programming Apr 12, 2024

เห็นหัวข้อมันดู geek แน่ ๆ เลย จริง ๆ มันมีหลักการและเหตุผลบางอย่างประกอบ เราเลยมาอธิบายแบบง่าย ๆ แบบเห็นภาพว่าทำไม จากประสบการณ์ที่เคยทำแอพเกี่ยวกับ social มาก่อน

ทำไมถึงต้องใช้ .

ก่อนอื่นเลย หลาย ๆ คนคงจะเคยเห็น content ประมาณนี้จากเพจเรามาบ้างแล้ว และแน่นอนว่าเพจอื่นก็มี content ประมาณนี้เช่นกัน

ความเหมือนกัน ตรงเนื้อหา สังเกตได้ว่า ระหว่างบรรทัดมี . คั่นอยู่เหมือนกัน

ลองดูโพสที่เนื้อหาเหมือนกัน แต่ไม่มี . ทุกคนคิดเห็นอย่างไรบ้างนะ อ่านแล้วดูเป็นยังไง ชอบอันไหนมากกว่า อันไหนอ่านง่ายกว่า

การที่เราเขียนบรรทัดใหม่บน Facebook นั้น เราก็กด enter ไป

ที่นี้เราอยากเว้นอีกบรรทัดนึงเพื่อให้มันอ่านง่ายขึ้น แต่แล้วพอโพสไป มันก็เอา enter ที่เหมือนกันออกไป เลยเหมือนขึ้นบรรทัดใหม่นั่นเอง

พูดแบบ coding ง่าย ๆ คือ การที่เรา enter คือเป็นการขึ้นบรรทัดใหม่ เป็น \n แล้วที่นี้เรา enter สักสามที มันจะเป็น \n\n\n แต่พอมันเอาไปขึ้นหน้าโพสจริง มันจะลด \n ที่เกินมา เหลือแค่ \n เดียว ซึ่งอาจจะถูกตัดไปตอนโพสแหละ

ปล. บางแอพ \n\n เป็น text block ใหม่นะ

ข้อมูลแต่ละ post ประกอบด้วยอะไรบ้าง

จากประสบการณ์ที่เคยทำแอพเกี่ยวกับ social มา เราพอจะรู้แหละว่าแต่ละแอพมันจะมีอะไรคล้าย ๆ กัน

สมมุติว่าหน้า feed ของเพจ เราเรียก 10 post ล่าสุดขึ้นมา อันนี้เราเรียกเป็น list ของก้อนที่เรียกว่า post ก็แล้วกัน ถ้าเป็น coding จะประมาณนี้ ArrayList<Post>

val profilePost = arrayListOf(
    Post(...),
    Post(...),
    Post(...),
    Post(...),
    Post(...),
    Post(...),
    Post(...),
    Post(...),
    Post(...),
    Post(...)
)

แต่ละ Post() ข้างในก็จะมี content ต่าง ๆ ภายใน อย่าง item แรกเป็นประมาณนี้แล้วกัน

Post(
    id = 100,
    content = arrayListOf(
        ContentItem(
            type = ContentType.TEXT
            text = "เคยสับสนไหมว่า Empty กับ Blank ต่างกันยังไง?\n.\nแน่นอน ทางนี้จำถูก จำผิดตลอดเลย55555555\nแล้วต่างกันยังไง ไปดูกัน\nกับตัวอย่างที่เป็นภาษา Kotlin ..."
        ),
        ContentItem(
            type = ContentType.IMAGE
            imageUrl = "https://example.com/post.jpg"
        )
    ),
    // ตรงนี้ใส่ให้เต็มเฉย ๆ เอาไป render ว่าใครเป็นคนโพส โพสเมื่อไหร่
    createdAt = "2023-04-16T18:38:36",
    user = User(
        userId = 6238545,
        userName = "MikkiPastel",
        avatarUrl = "https://example.com/avatar.jpg"
    ),
    stat = Stat(
        like = 100,
        share = 2,
        comment = 0
    )
)

มาดู class ที่ใช้คร่าว ๆ จะมี Post() กับ ContentItem() เนอะ โดยตัว ContentType เป็น enum class เนอะ ง่าย ๆ คือบอกว่า ContentItem ของเรานั้น มีทั้งหมด 4 type คือ text image video link

data class Post(
    val id: Int,
    val content: ArrayList<ContentItem>,
    val createdAt: String
    val user: User,
    val stat: Stat
)

data class ContentItem(
    val type: ContentType,
    val text: String?,
    val imageUrl: String?,
    val videoUrl: String?
    val linkUrl: String?
)

enum class ContentType {
    TEXT, IMAGE, VIDEO, LINK
}

// ตรงนี้ใส่ให้เต็มเฉย ๆ เอาไป render ว่าใครเป็นคนโพส โพสเมื่อไหร่
data class User(
    val userId: Int,
    val userName: String,
    val avatarUrl: String?
)

data class Stat(
    val like: Int,
    val share: Int,
    val comment: Int
)

และแต่ละองค์ประกอบเรียงร้อยออกมาเป็น post ซึ่งแน่นอนว่า image video และ link มันจะอยู่ล่างสุดเสมอ สำหรับ Facebook นะ ส่วนแอพอื่นอาจจะวางพวก media อื่นสลับกับ text ได้

เอามาขึ้น UI จริง

หน้าที่ของหน้าบ้าน คือไปเรียก API มา แล้วเอาข้อมูลที่ได้มาแสดง

เบื้องต้นเราจะได้ 10 post เอามาขึ้น UI โดยมองว่าเราจะมีหน้าตาแบบนี้ 10 อัน เรียงกันแบบนี้

และในแต่ละอันจะมี content ของ post นั้น ๆ อยู่ด้วย เราก็ render โดยการ check type ของ element ว่าเป็นอันไหน แสดงตามที่ได้

อันนี้เป็นตัวอย่าง Adapter class ในการแสดง content หน้าตาประมาณนี้ แต่ละ type ก็จะมีการแสดงผลเป็นของตัวเอง

class PostContentAdapter(
    private val contentItems: List<ContentItem>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    override fun getItemCount() = contentItems.size

    override fun getItemViewType(position: Int): Int {
        return contentItems[position].type.ordinal
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (ContentType.values()[viewType]) {
            ContentType.TEXT -> TextViewHolder(
                LayoutInflater.from(parent.context)
                    .inflate(R.layout.item_text_content, parent, false)
            )
            ContentType.IMAGE -> ImageViewHolder(
                LayoutInflater.from(parent.context)
                    .inflate(R.layout.item_image_content, parent, false)
            )
            ContentType.VIDEO -> VideoViewHolder(
                LayoutInflater.from(parent.context)
                    .inflate(R.layout.item_video_content, parent, false)
            )
            ContentType.LINK -> LinkViewHolder(
                LayoutInflater.from(parent.context)
                    .inflate(R.layout.item_link_content, parent, false)
            )
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val contentItem = contentItems[position]
        when (holder) {
            is TextViewHolder -> holder.bind(contentItem)
            is ImageViewHolder -> holder.bind(contentItem)
            is VideoViewHolder -> holder.bind(contentItem)
            is LinkViewHolder -> holder.bind(contentItem)
        }
    }

    ...
}

สำหรับ text ในการแสดงผล ก็แสดงผลตรง ๆ ตามที่ได้รับจาก API เลย

class TextViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    private val textView: TextView = itemView.findViewById(R.id.textView)

    fun bind(contentItem: ContentItem) {
        textView.text = contentItem.text
    }
}

ในเมื่อตอนสร้างโพสตัดให้เหลือ enter เดียวแล้ว

ดังนั้นการใส่ . เพื่อคั่นระหว่างบรรทัด เป็นการสร้าง text ที่มี . ทำให้ดูมีระยะห่างระหว่างกันมากขึ้นเนอะ ดูอ่านง่ายขึ้นนั่นเอง

ปล. ของเว็บเข้าใจว่าเราน่าจะ spilt \n แล้วมาขึ้นในแต่ละ element ของ content

ในมุมของ content creator

แน่นอนว่าเราอยากให้ content คุณภาพที่เราตั้งใจทำนั้น ทุกคนชอบ มี engagement ดี ๆ กันใช่ไหมล่ะ ซึ่งเราก็ไม่อยากให้คนอื่นเลื่อนผ่านไป

การเขียนให้อ่านได้ง่าย ก็เป็นหนึ่งในปัจจัยที่ทำให้เห็นโพสเราแล้วอยากอ่านต่อ ถ้าเราเห็น text ติดกันเป็นพรึ้ด เราก็คงไม่อยากอ่านใช่ไหมล่ะ

การใส่ . คั่นในแต่ละส่วนของบทความนั้น ช่วยแก้ปัญหา text ที่ติดกันเป็นพรึ้ด ให้ดูอ่านง่ายขึ้น

แต่การเขียนโพสมีหัวข้อใหญ่ และมีหัวข้อย่อยลงมาด้วย บางคนอาจจะใส่ hashtag ที่หัวข้อย่อยช่วย หรืออาจจะใส่ emoji นำหน้า และมีอีกหนึ่งวิธี คือ การใช้ . อีกหนึ่งบรรทัด ในการแยกเนื้อหาหัวข้อย่อยออกจากกัน

ตัวอย่างจ้า

.

หวังว่าทุกคนจะได้ประโยชน์ไม่น้อยก็มากเนอะ


ติดตามข่าวสารตามช่องทางต่าง ๆ และทุกช่องทางโดเนทกันไว้ที่นี่เลย แนะนำให้ใช้ tipme เน้อ ผ่าน promptpay ได้เต็มไม่หักจ้า

ติดตามข่าวสารแบบไว ๆ มาที่ Twitter เลย บางอย่างไม่มีในบล็อก และหน้าเพจนะ

Tags

Minseo Chayabanjonglerd

I am a full-time Android Developer and part-time contributor with developer community and web3 world, who believe people have hard skills and soft skills to up-skill to da moon.