Post updated on 13th October, 2020 at 07:30 pm
Android এ আমরা সাধারনত বিভিন্ন layout এর ভিতর layout বসিয়ে ভিউ তৈরি করি। লিস্ট দেখানোর জন্য প্রথমত আমরা ব্যবহার করি ListView. লিস্ট ভিউতে কাজ করতে গিয়ে যখন একাধিক component একেকটা list item এর ভিতর থাকে তখন আমরা Custom ListView ব্যবহার করি। কাস্টম লিস্ট ভিউয়ের মতই কিন্তু অনেক বেশি ভাল পার্ফর্মেন্স দিয়ে থাকে RecyclerView.
যখন বেশি পরিমান ডেটা কোনো লিস্টে দেখানোর দরকার হয় তখন RecyclerView লিস্টভিউয়ের চেয়ে ভাল কাজ করে। রিসাইক্লার ভিউয়ের ভিতর কোনো একটা ভিউ বা লেয়াউট recycle করা হয়। সেটা হতে পারে একটা Linear বা Relative Layout. অর্থাৎ আমরা একটা xml ফাইলে আমাদের একটা আইটেমের জন্য UI ডিজাইন করব। ঐ লেয়াউটটা রিসাইক্লার ভিউয়ের মাধ্যমে প্রতিটা আইটেমে ভিন্ন ভিন্ন ডেটা দিয়ে লোড করানো হবে। এখানে সাধারন লেয়াউট ব্যবহার না করে চমৎকার একটা ভিউ ব্যবহার করতে পারি। তা হচ্ছে CardView. CardView ব্যবহার করলে ইউজার ইন্টারফেসটা বেশ সুন্দর হয়। Material Design এর কনসেপ্ট অনুযায়ী এই ভিউতে সহজেই পরিমিত shadow যোগ করা যায়।
আমাদের এই পোস্টের লক্ষ্য হচ্ছে নিচের ছবির মত একটা ভিউ তৈরি করা। এর উপরের অংশে থাকবে popular item list. এটা horizontally scrollable. আর নিচের অংশে থাকবে vertically scrollable data item list. ডেটাগুলো আসবে সার্ভার থেকে JSON ফরমেটে। প্রতিটা আইটেমে ক্লিক করলে নামটা Toast message এ দেখাবে।
কাজটা করার জন্য ব্যবহার করেছিঃ
* CardView
* RecyclerView
* Retrofit Network Library
* Picasso image loading library
* POJO Generator Plugin of Android Studio
Vertically যেই লিস্টটা স্ক্রল করা যাবে সেটা করতে আমরা RecyclerView এর ভিতর CardView ব্যবহার করব। আর Horizontal List এ RecyclerView এর ভিতরে একটা linear layout কে recycle করে শো করব। উপরের ছবিটা দেখলে সাধারন লিনিয়ার লেয়াউট আর কার্ডভিউয়ের মধ্যকার পার্থক্যটা স্পষ্ট হবে।
Popular List এর প্রতিটা আইটেমের চেহারা ডিজাইন করা হয়েছে এই popular_single_item.xml ফাইলের মাধ্যমে। এখানে কার্ডভিউ ব্যবহার করি নাই। আপনারা চাইলে কার্ডভিউ ব্যবহার করতে পারেন।
Data list তথা horizontal list এর আইটেমগুলো শো করার জন্য CardView ব্যবহার করে data_single_item.xml ডিজাইন করা হয়েছে।
CardView ও RecyclerView ব্যবহার করার জন্য gradle file এর dependencies
এ যোগ করুন নিচের লাইনগুলোঃ
dependencies { [...] compile 'com.android.support:cardview-v7:25.1.1' compile 'com.android.support:recyclerview-v7:25.1.1' }
Gradle এ সর্বশেষ ভার্সন যুক্ত করার জন্য ব্যবহার করতে পারেন এই টুলটি।
data_single_item.xml ফাইলে যোগ করুন এই widget টি। এর ভিতর দরকার মত ImageView, TextView যোগ করুন।
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/card_view" android:layout_gravity="center" android:layout_width="match_parent" android:layout_height="match_parent" card_view:cardCornerRadius="4dp"> // full code </android.support.v7.widget.CardView>
card_view:cardCornerRadius=”4dp” এর মাধ্যমে কার্ডের corner-গুলো একটু round shape করা হয়েছে। এই attribute এর value বাড়িয়ে কমিয়ে রাউন্ড শেপের পরিমান পরীক্ষা করে দেখতে পারেন।
যেহেতু দুইটি RecyclerView তাই দুইটি ভিন্ন ভিন্ন Adapter Class ব্যবহার করা হয়েছে। যে কোনো একটা বুঝলেই যে কোনো অ্যাডাপটার বুঝা যাবে। এখানে VerticalAdapter.java ক্লাস নিয়ে আলোচনা করা হচ্ছে।
VerticalAdapter ক্লাসকে extend করছি RecyclerView.Adapter ক্লাস দিয়ে । যেখানে CustomViewHolder এই একই ক্লাসের মধ্যে বানানো আরেকটা ক্লাস। CustomViewHolder এর কোডগুলো হচ্ছেঃ
class CustomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { ImageView fullImage; ImageView profileImage; TextView nameTextView; TextView profileName; TextView timeStamp; CardView cardView; CustomViewHolder(View itemView) { super(itemView); nameTextView = (TextView) itemView.findViewById(R.id.name_text_view); profileName = (TextView) itemView.findViewById(R.id.profile_name); timeStamp = (TextView) itemView.findViewById(R.id.time_stamp); fullImage = (ImageView) itemView.findViewById(R.id.full_image); profileImage = (ImageView) itemView.findViewById(R.id.profile_image); cardView = (CardView) itemView.findViewById(R.id.card_view); cardView.setOnClickListener(this); } @Override public void onClick(View v) { int clickedPosition = getAdapterPosition(); Toast.makeText(context, dataList.get(clickedPosition).getName(), Toast.LENGTH_LONG).show(); } }
RecyclerView.ViewHolder কে extend ও View.OnClickListener কে implement করা হয়েছে। Error দিবে OnClickListener এর onClick() মেথডটা override করার জন্য। এর মাধ্যমেই আমরা ভিউতে ক্লিক করলে সেই ইভেন্টের মাধ্যমে Toast Message দেখাতে পারব। শুধু টোস্টই না, চাইলে অন্য কোনো activity-fragment এ নিয়ে যাওয়া যাবে। অথবা এই কার্ডটাকে expand করে আরো বিস্তারিত কনটেন্ট দেখানো যেতে পারে। একটা ভিউতে ক্লিক করলে সেটিকে expand করে আরো কিছু কনটেন্ট দেখানোর একটা ভাল লাইব্রেরি হচ্ছে ExpandableLayout. ExpandableLayout এর উপর জানার জন্য পড়তে পারেন আমার ব্লগের এই লেখাটি।
UI-তে ব্যবহৃত widget-গুলো এই ক্লাসের ভিতর declare ও constructor এর ভিতর initialize করা হয়েছে।
এই ক্লাসটা হচ্ছে আমাদের নিজেদের বানানো (customize করা) ভিউকে hold করার জন্য একটা view holder. এই ভিউ হোল্ডারকে ব্যবহার করে VerticalAdapter class এর অবজেক্ট ManActivity তে ডেটা শো করে। UI, view holder ও data-র মাঝে মেলবন্ধন তৈরি করার জন্য এডাপটার ব্রিজ হিসাবে কাজ করে।
ViewHolder এর সাথে adapter কে bind করা হবে এই কোডের মাধ্যমেঃ
@Override public void onBindViewHolder(VerticalAdapter.CustomViewHolder holder, int position) { Datum datum = dataList.get(position); Picasso.with(context) .load(datum.getImage()) .into(holder.fullImage); holder.nameTextView.setText(datum.getTitle()); Picasso.with(context) .load(datum.getNameImage()) .transform(new CircleTransform()) .into(holder.profileImage); holder.profileName.setText(datum.getName()); }
ইমেজ শো করা, টেক্সট শো করা ইত্যাদি কাজগুলো এখানে হচ্ছে। ১৪ নাম্বার লাইনে .transform(new CircleTransform()) এর মাধ্যমে round shape এ ছোট্ট করে profile picture এর মত ইমেজ সেট করা হয়েছে। CircleTransform ক্লাসটি মূল প্রোজেক্টের HelperClasses প্যাকেজে পাওয়া যাবে।
পুরো ক্লাসটা চাইলে এখান থেকে দেখতে পারেন।
কোথায় ডেটা দেখানো হবে, ক্লিক করলে কী হবে ইত্যাদি বিষয়গুলো এতক্ষণ ঠিক করলাম। এখনো কিন্তু আমরা সত্যিকারের ডেটা নিয়ে কাজ করি নাই। মানে সার্ভার থেকে ডেটা আনার কাজ বাকি রয়েছে। MainActivity থেকে Retrofit network library ব্যবহার করে এই JSON ডেটাগুলো নিয়ে আসা হবে।
Retrofit নিয়ে এখানে আলোচনা করব না। Retrofit নেটওয়ার্ক লাইব্রেরির উপর লেখা বিস্তারিত পোস্টটি পড়া যাবে এখান থেকে।
MainActivity তে দুইটা recyclerview initialize করা হচ্ছেঃ
recyclerViewHorizontal = (RecyclerView) findViewById(R.id.horizontal_recycler_view); recyclerViewVertical = (RecyclerView) findViewById(R.id.vertical_recycler_view); recyclerViewHorizontal.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false)); recyclerViewVertical.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));
নেটওয়ার্কে কল দিয়ে ডেটা পাওয়া গেলে adapter initialize হবে ও সেট হবেঃ
horizontalAdapter = new HorizontalAdapter(MainActivity.this, popularList); recyclerViewHorizontal.setAdapter(horizontalAdapter); verticalAdapter = new VerticalAdapter(MainActivity.this, dataList); recyclerViewVertical.setAdapter(verticalAdapter);
ব্যস! মূল কাজ শেষ।
পোস্টটা নিজের কাছেই কেমন যেন অগোছালো মনে হচ্ছে। কোথাও কোথাও conceptual mistake থাকতে পারে। আপনার চোখে পড়লে অনুগ্রহ করে কমেন্ট করে জানাবেন। অথবা এই approach এ না করে আরো ভাল ভাবে কাজটা করা গেলে সেটাও কাইন্ডলি জানাবেন।
পুরো প্রোজেক্টের কোড একত্রে পাওয়া যাবে গিটহাব রিপোজিটরিতে।
অসংখ্য ধন্যবাদ ভাই ।
baal likhsen! bujhi nai
ধন্যবাদ আপনার “সুন্দর” মন্তব্যের জন্য। আপনার পারিবারিক শিক্ষা আর বংশ মর্যাদা সম্পর্কে এখানে স্পষ্ট ধারণা না দিলেও পারতেন। যতজন মানুষ এসে আপনার কমেন্ট দেখবে ততজনই আপনার বাবা মায়ের উপর বিরক্ত হবেন আপনার মত সন্তানের বাবা-মা হওয়ার জন্য। আপনার জন্য আপনার বাবা-মাকে হয়ত সারা জীবনই গালি খাইয়ে যাবেন আপনি।
আপনার না বুঝার পেছনে আমার লেখার দুর্বলতা থাকতে পারে। একই সাথে আপনার অজ্ঞতাও থাকতে পারে। অ্যান্ড্রয়েড আর প্রোগ্রামিংয়ের ব্যসিক জ্ঞান দরকার এটা বুঝার জন্য। সেগুলো না থাকলে বুঝা যাবে না। প্রোগ্রামিংয়ের “অ আ ক খ” প্রথমে শিখুন। এরপর অ্যান্ড্রয়েড নিয়ে কাজ করুন। আর ভাষাকে মার্জিত করুন। গালি দেয়া খারাপ ভাষা প্রয়োগ করা ফাসিক ব্যক্তির কাজ। কিছু শেখার জন্য আগে এই মানসিকতা দরকার যে “আমি পারি না, শিখতে চাই”। না বুঝলে এই মানসিকতা দরকার “নিশ্চয়ই আমার বুঝার ক্ষেত্রে দুর্বলতা আছে, তাই বুঝি নাই”। তাহলে ইনশাআল্লাহ শেখার ক্ষেত্রে বুঝার ক্ষেত্রে তা সহায়ক হবে। আর যদি আপনার পারিবারিক শিক্ষার অভাবে উপরের মত ভাষা প্রয়োগ করেন, তাহলে ইনশাআল্লাহ এরকমই থেকে যাবেন। কখনোই বুঝবেন না!
আল্লাহ আপনাকে হেদায়েত দান করুন। বিষাক্ত মানসিকতা থেকে মুক্তি দান করুন।