MDC-102 Android: উপাদান গঠন এবং বিন্যাস (জাভা)

১. ভূমিকা

logo_components_color_2x_web_96dp.png

ম্যাটেরিয়াল কম্পোনেন্টস (MDC) ডেভেলপারদের ম্যাটেরিয়াল ডিজাইন বাস্তবায়ন করতে সাহায্য করে। গুগলের একদল ইঞ্জিনিয়ার এবং ইউএক্স ডিজাইনার দ্বারা তৈরি, MDC-তে কয়েক ডজন সুন্দর এবং কার্যকরী UI কম্পোনেন্ট রয়েছে এবং এটি অ্যান্ড্রয়েড, আইওএস, ওয়েব এবং ফ্লাটারের জন্য উপলব্ধ। material.io/develop

কোডল্যাব MDC-101-এ, আপনি একটি লগইন পেজ তৈরি করতে দুটি ম্যাটেরিয়াল কম্পোনেন্ট (MDC) ব্যবহার করেছেন: টেক্সট ফিল্ড এবং বাটন। এখন চলুন নেভিগেশন, কাঠামো এবং ডেটা যোগ করে এই ভিত্তিটিকে আরও বিস্তৃত করি।

আপনি যা তৈরি করবেন

এই কোডল্যাবে, আপনি Shrine নামক একটি অ্যাপের জন্য একটি হোম স্ক্রিন তৈরি করবেন, যেটি পোশাক এবং গৃহস্থালীর সামগ্রী বিক্রি করে এমন একটি ই-কমার্স অ্যাপ। এতে থাকবে:

  • একটি শীর্ষ অ্যাপ বার
  • পণ্যগুলির একটি গ্রিড তালিকা

249db074eff043f4.png

এই কোডল্যাবে MDC-অ্যান্ড্রয়েড উপাদানসমূহ

  • অ্যাপবারলেআউট
  • ম্যাটেরিয়ালকার্ডভিউ

আপনার যা যা লাগবে

  • অ্যান্ড্রয়েড ডেভেলপমেন্টের প্রাথমিক জ্ঞান
  • অ্যান্ড্রয়েড স্টুডিও (আপনার কাছে না থাকলে এখান থেকে ডাউনলোড করুন)
  • একটি অ্যান্ড্রয়েড এমুলেটর বা ডিভাইস (অ্যান্ড্রয়েড স্টুডিওর মাধ্যমে উপলব্ধ)
  • নমুনা কোড (পরবর্তী ধাপ দেখুন)

অ্যান্ড্রয়েড অ্যাপ তৈরিতে আপনার অভিজ্ঞতার স্তরকে আপনি কীভাবে মূল্যায়ন করবেন?

শিক্ষানবিশ মধ্যবর্তী দক্ষ

২. আপনার ডেভেলপমেন্ট এনভায়রনমেন্ট সেট আপ করুন।

MDC-101 এর ধারাবাহিকতায়?

আপনি যদি MDC-101 সম্পন্ন করে থাকেন, তাহলে আপনার কোড এই কোডল্যাবের জন্য প্রস্তুত থাকা উচিত। আপনি সরাসরি ধাপ ৩: একটি টপ অ্যাপ বার যোগ করুন -এ যেতে পারেন।

একেবারে নতুন করে শুরু করছেন?

স্টার্টার কোডল্যাব অ্যাপটি ডাউনলোড করুন

স্টার্টার অ্যাপটি material-components-android-codelabs-102-starter/java ডিরেক্টরিতে অবস্থিত। শুরু করার আগে অবশ্যই ওই ডিরেক্টরিতে cd

...অথবা গিটহাব থেকে এটি ক্লোন করুন

গিটহাব থেকে এই কোডল্যাবটি ক্লোন করতে, নিম্নলিখিত কমান্ডগুলো চালান:

git clone https://github.com/material-components/material-components-android-codelabs
cd material-components-android-codelabs/
git checkout 102-starter

অ্যান্ড্রয়েড স্টুডিওতে স্টার্টার কোড লোড করুন।

  1. সেটআপ উইজার্ড শেষ হয়ে গেলে এবং ' Welcome to Android Studio' উইন্ডোটি দেখা গেলে, 'Open an existing Android Studio project'-এ ক্লিক করুন। যে ডিরেক্টরিতে আপনি স্যাম্পল কোডটি ইনস্টল করেছিলেন সেখানে যান এবং Shrine প্রজেক্টটি খোলার জন্য java -> shrine নির্বাচন করুন (অথবা আপনার কম্পিউটারে shrine লিখে সার্চ করুন)।
  2. অ্যান্ড্রয়েড স্টুডিও উইন্ডোর নিচের দিকে অ্যাক্টিভিটি ইন্ডিকেটরগুলোতে যেমনটা দেখানো হচ্ছে, প্রজেক্টটি বিল্ড ও সিঙ্ক হওয়ার জন্য কিছুক্ষণ অপেক্ষা করুন।
  3. এই পর্যায়ে, অ্যান্ড্রয়েড স্টুডিও কিছু বিল্ড এরর দেখাতে পারে, কারণ আপনার কাছে অ্যান্ড্রয়েড এসডিকে বা বিল্ড টুলস নেই, যেমনটি নিচে দেখানো হয়েছে। এগুলো ইনস্টল/আপডেট করতে এবং আপনার প্রজেক্ট সিঙ্ক করতে অ্যান্ড্রয়েড স্টুডিওর নির্দেশাবলী অনুসরণ করুন।

F5H6srsw_5xOPGFpKrm1RwgewatxA_HUbDI1PWoQUAoJcT6DpfBOkAYwq3S-2vUHvweUa FgAmG7BtUKkGouUbhTwXQh53qec8tO5eVecdlo7QIoLc8rNxFEBb8l7RlS-KzBbZOzVhA

প্রকল্পের নির্ভরতা যোগ করুন

প্রজেক্টটির জন্য MDC অ্যান্ড্রয়েড সাপোর্ট লাইব্রেরির উপর নির্ভরতা প্রয়োজন। আপনার ডাউনলোড করা স্যাম্পল কোডে এই নির্ভরতাটি আগে থেকেই তালিকাভুক্ত থাকার কথা, কিন্তু তা নিশ্চিত করার জন্য নিম্নলিখিত পদক্ষেপগুলো অনুসরণ করা ভালো।

  1. app মডিউলের build.gradle ফাইলে যান এবং নিশ্চিত করুন যে dependencies ব্লকে MDC Android-এর উপর একটি ডিপেন্ডেন্সি অন্তর্ভুক্ত আছে:
api 'com.google.android.material:material:1.1.0-alpha06'
  1. (ঐচ্ছিক) প্রয়োজনে, build.gradle ফাইলটি সম্পাদনা করে নিম্নলিখিত ডিপেন্ডেন্সিগুলো যোগ করুন এবং প্রজেক্টটি সিঙ্ক করুন।
dependencies {
    api 'com.google.android.material:material:1.1.0-alpha06'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'com.android.volley:volley:1.1.1'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21"
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:core:1.1.0'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test:runner:1.2.0-alpha05'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha05'
}

স্টার্টার অ্যাপটি চালান

  1. নিশ্চিত করুন যে রান / প্লে বাটনের বাম দিকের বিল্ড কনফিগারেশনটি app হিসেবে সেট করা আছে।
  2. অ্যাপটি বিল্ড ও রান করতে সবুজ রান / প্লে বাটনটি চাপুন।
  3. 'Select Deployment Target' উইন্ডোতে, আপনার উপলব্ধ ডিভাইসগুলোর তালিকায় যদি আগে থেকেই কোনো অ্যান্ড্রয়েড ডিভাইস তালিকাভুক্ত থাকে, তাহলে সরাসরি ধাপ ৮- এ চলে যান। অন্যথায়, 'Create New Virtual Device'-এ ক্লিক করুন।
  4. হার্ডওয়্যার নির্বাচন স্ক্রিনে, পিক্সেল ২-এর মতো একটি ফোন ডিভাইস নির্বাচন করুন এবং তারপরে পরবর্তী (Next) ক্লিক করুন।
  5. সিস্টেম ইমেজ স্ক্রিনে, একটি সাম্প্রতিক অ্যান্ড্রয়েড সংস্করণ নির্বাচন করুন, বিশেষত সর্বোচ্চ এপিআই লেভেলেরটি। যদি এটি ইনস্টল করা না থাকে, তবে প্রদর্শিত ডাউনলোড লিঙ্কে ক্লিক করুন এবং ডাউনলোডটি সম্পূর্ণ করুন।
  6. পরবর্তী ধাপে যান।
  7. অ্যান্ড্রয়েড ভার্চুয়াল ডিভাইস (AVD) স্ক্রিনে, সেটিংস অপরিবর্তিত রেখে ফিনিশ-এ ক্লিক করুন।
  8. ডেপ্লয়মেন্ট টার্গেট ডায়ালগ থেকে একটি অ্যান্ড্রয়েড ডিভাইস নির্বাচন করুন।
  9. Ok ক্লিক করুন।
  10. অ্যান্ড্রয়েড স্টুডিও অ্যাপটি বিল্ড করে, ডেপ্লয় করে এবং টার্গেট ডিভাইসে স্বয়ংক্রিয়ভাবে খুলে দেয়।

সফল! আপনি MDC-101 কোডল্যাব থেকে Shrine লগইন পেজটি দেখতে পাবেন।

4cb0c218948144b4.png

এখন যেহেতু লগইন স্ক্রিনটি দেখতে ভালো লাগছে, চলুন অ্যাপটিতে কিছু পণ্য যুক্ত করা যাক।

৩. একটি টপ অ্যাপ বার যোগ করুন

লগইন পেজটি বন্ধ করলে হোম স্ক্রিনটি দেখা যায়, যেখানে লেখা থাকে "আপনি পেরেছেন!"। এটা দারুণ! কিন্তু এখন আমাদের ব্যবহারকারীর করার মতো কোনো কাজ নেই, বা অ্যাপের মধ্যে তিনি কোথায় আছেন, সে সম্পর্কেও কোনো ধারণা নেই। এই সমস্যা সমাধানে, চলুন নেভিগেশন যোগ করা যাক।

ম্যাটেরিয়াল ডিজাইন এমন নেভিগেশন প্যাটার্ন প্রদান করে যা উচ্চ মাত্রার ব্যবহারযোগ্যতা নিশ্চিত করে। এর অন্যতম উল্লেখযোগ্য নেভিগেশন উপাদান হলো টপ অ্যাপ বার।

নেভিগেশনের সুবিধা দিতে এবং ব্যবহারকারীদের অন্যান্য কাজে দ্রুত অ্যাক্সেস করার জন্য, চলুন একটি টপ অ্যাপ বার যোগ করি।

একটি অ্যাপবার উইজেট যোগ করুন

shr_product_grid_fragment.xml ফাইলে, "You did it!" TextView টি থাকা <LinearLayout> ট্যাগটি মুছে ফেলুন এবং এর পরিবর্তে নিম্নলিখিত কোডটি ব্যবহার করুন:

shr_product_grid_fragment.xml

<com.google.android.material.appbar.AppBarLayout
   android:layout_width="match_parent"
   android:layout_height="wrap_content">

   <androidx.appcompat.widget.Toolbar
       android:id="@+id/app_bar"
       style="@style/Widget.Shrine.Toolbar"
       android:layout_width="match_parent"
       android:layout_height="?attr/actionBarSize"
       app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>

আপনার shr_product_grid_fragment.xml দেখতে নিম্নলিখিতের মতো হওয়া উচিত:

shr_product_grid_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".ProductGridFragment">

   <com.google.android.material.appbar.AppBarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content">

       <androidx.appcompat.widget.Toolbar
           android:id="@+id/app_bar"
           style="@style/Widget.Shrine.Toolbar"
           android:layout_width="match_parent"
           android:layout_height="?attr/actionBarSize"
           app:title="@string/shr_app_name" />
   </com.google.android.material.appbar.AppBarLayout>
  
</FrameLayout>

অনেক অ্যাপ বারে শিরোনামের পাশে একটি বাটন থাকে। চলুন আমাদেরটিতে একটি মেনু আইকন যোগ করি।

একটি নেভিগেশন আইকন যোগ করুন

shr_product_grid_fragment.xml ফাইলে থাকা অবস্থায়, Toolbar XML কম্পোনেন্টে (যা আপনি এইমাত্র আপনার লেআউটে যোগ করেছেন) নিম্নলিখিত কোডটি যোগ করুন:

shr_product_grid_fragment.xml

app:navigationIcon="@drawable/shr_menu"

আপনার shr_product_grid_fragment.xml দেখতে নিম্নলিখিতের মতো হওয়া উচিত:

shr_product_grid_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".ProductGridFragment">
  
   <com.google.android.material.appbar.AppBarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content">

       <androidx.appcompat.widget.Toolbar
           android:id="@+id/app_bar"
           style="@style/Widget.Shrine.Toolbar"
           android:layout_width="match_parent"
           android:layout_height="?attr/actionBarSize"
           app:navigationIcon="@drawable/shr_menu"
           app:title="@string/shr_app_name" />
   </com.google.android.material.appbar.AppBarLayout>
  
</FrameLayout>

অ্যাকশন বাটন যোগ করুন এবং টপ অ্যাপ বারটি স্টাইল করুন।

আপনি অ্যাপ বারের শেষ প্রান্তে বাটন যোগ করতে পারেন। অ্যান্ড্রয়েডে এগুলোকে অ্যাকশন বাটন বলা হয়।

আমরা টপ অ্যাপ বারটিকে স্টাইল করব এবং প্রোগ্রাম্যাটিকভাবে এর মেনুতে অ্যাকশন বাটন যোগ করব।

প্রথমে, টুলবার সেট আপ করার জন্য একটি মেথড তৈরি করা যাক। মেথডটি তার id ব্যবহার করে টুলবারের একটি রেফারেন্স নেবে এবং getActivity() ব্যবহার করে অ্যাক্টিভিটিরও একটি রেফারেন্স নেবে। যদি অ্যাক্টিভিটিটি null না হয়, তাহলে setSupportActionBar ব্যবহার করে Toolbar ActionBar হিসেবে সেট করুন।

ProductGridFragment.java

private void setUpToolbar(View view) {
   Toolbar toolbar = view.findViewById(R.id.app_bar);
   AppCompatActivity activity = (AppCompatActivity) getActivity();
   if (activity != null) {
       activity.setSupportActionBar(toolbar);
   }
}

এরপরে, আমরা এইমাত্র যোগ করা setUpToolbar মেথডটির ঠিক নিচে, shr_toolbar_menu.xml ফাইলের বিষয়বস্তু টুলবারে যুক্ত করার জন্য onCreateOptionsMenu ওভাররাইড করি:

ProductGridFragment.java

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
   menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
   super.onCreateOptionsMenu(menu, menuInflater);
}

এখন, onCreateView() মেথডের কন্টেন্টে আমরা যে setUpToolbar মেথডটি যোগ করেছিলাম, সেটিকে নিম্নলিখিত কোড সহ কল ​​করুন:

ProductGridFragment.java

@Override
public View onCreateView(
       @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
   // Inflate the layout for this fragment with the ProductGrid theme
   View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);

   // Set up the toolbar
   setUpToolbar(view);

   return view;
}

সবশেষে, ProductGridFragment.java তে একটি onCreate() মেথড যোগ করুন। মেথডের বডিতে, setHasOptionMenu প্যারামিটারটি true হিসেবে সেট করুন।

পদ্ধতিটি দেখতে এইরকম হওয়া উচিত:

ProductGridFragment.java

@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setHasOptionsMenu(true);
}

উপরের কোডটি আমাদের XML লেআউট থেকে অ্যাপ বারটিকে এই অ্যাক্টিভিটির অ্যাকশন বার হিসেবে সেট করে। onCreateOptionsMenu কলব্যাকটি অ্যাক্টিভিটিকে বলে দেয় যে মেনু হিসেবে কী ব্যবহার করতে হবে। এক্ষেত্রে, এটি R.menu.shr_toolbar_menu থেকে মেনু আইটেমগুলো অ্যাপ বারে যুক্ত করবে।

মেনু ফাইলটিতে দুটি আইটেম রয়েছে: 'সার্চ' এবং 'ফিল্টার'।

shr_toolbar_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto">
   <item
       android:id="@+id/search"
       android:icon="@drawable/shr_search"
       android:title="@string/shr_search_title"
       app:showAsAction="always" />
   <item
       android:id="@+id/filter"
       android:icon="@drawable/shr_filter"
       android:title="@string/shr_filter_title"
       app:showAsAction="always" />
</menu>

এই পরিবর্তনগুলোর পর, আপনার ProductGridFragment.java ফাইলটি দেখতে নিচের মতো হবে:

ProductGridFragment.java

package com.google.codelabs.mdc.java.shrine;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;


public class ProductGridFragment extends Fragment {

   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setHasOptionsMenu(true);
   }
  
   @Override
   public View onCreateView(
           @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       // Inflate the layout for this fragment with the ProductGrid theme
       View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);

       // Set up the toolbar
       setUpToolbar(view);

       return view;
   }
  
   private void setUpToolbar(View view) {
       Toolbar toolbar = view.findViewById(R.id.app_bar);
       AppCompatActivity activity = (AppCompatActivity) getActivity();
       if (activity != null) {
           activity.setSupportActionBar(toolbar);
       }
   }

   @Override
   public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
       menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
       super.onCreateOptionsMenu(menu, menuInflater);
   }

}

বিল্ড করুন এবং চালান। আপনার হোম স্ক্রিনটি দেখতে এইরকম হবে:

d04e8aa3b27f4754.png

এখন টুলবারের ডানদিকে একটি নেভিগেশন আইকন, একটি শিরোনাম এবং দুটি অ্যাকশন আইকন রয়েছে। টুলবারটি একটি হালকা ছায়ার মাধ্যমে উচ্চতাও প্রদর্শন করে, যা দেখায় যে এটি কন্টেন্ট থেকে ভিন্ন একটি লেয়ারে রয়েছে।

৪. একটি কার্ড যোগ করুন

এখন যেহেতু আমাদের অ্যাপটির একটি কাঠামো তৈরি হয়েছে, চলুন এর বিষয়বস্তুগুলোকে কার্ডে সাজিয়ে নিই।

একটি কার্ড যোগ করুন

টপ অ্যাপ বারের নিচে একটি কার্ড যোগ করার মাধ্যমে শুরু করা যাক। একটি কার্ডে ছবির জন্য একটি জায়গা, একটি শিরোনাম এবং অতিরিক্ত লেখার জন্য একটি লেবেল থাকা উচিত।

shr_product_grid_fragment.xml ফাইলে, AppBarLayout নিচে নিম্নলিখিত কোডটি যোগ করুন:

shr_product_grid_fragment.xml

<com.google.android.material.card.MaterialCardView
   android:layout_width="160dp"
   android:layout_height="180dp"
   android:layout_marginBottom="16dp"
   android:layout_marginLeft="16dp"
   android:layout_marginRight="16dp"
   android:layout_marginTop="70dp"
   app:cardBackgroundColor="?attr/colorPrimaryDark"
   app:cardCornerRadius="4dp">

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_gravity="bottom"
       android:background="#FFFFFF"
       android:orientation="vertical"
       android:padding="8dp">

       <TextView
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:padding="2dp"
           android:text="@string/shr_product_title"
           android:textAppearance="?attr/textAppearanceHeadline6" />

       <TextView
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:padding="2dp"
           android:text="@string/shr_product_description"
           android:textAppearance="?attr/textAppearanceBody2" />
   </LinearLayout>
</com.google.android.material.card.MaterialCardView>

নির্মাণ ও পরিচালনা:

f6184a55ccb5f920.png

এই প্রিভিউতে আপনি দেখতে পাচ্ছেন যে, কার্ডটি স্ক্রিনের বাম প্রান্ত থেকে কিছুটা ভেতরে বসানো আছে, এবং এর কোণাগুলো গোলাকার ও একটি ছায়া রয়েছে (যা কার্ডটির উচ্চতা প্রকাশ করে)। সম্পূর্ণ এলাকাটিকে "কন্টেইনার" বলা হয়। কন্টেইনারটি ছাড়া এর ভেতরের বাকি সমস্ত উপাদান ঐচ্ছিক।

আপনি একটি কন্টেইনারে নিম্নলিখিত উপাদানগুলি যোগ করতে পারেন: হেডার টেক্সট, একটি থাম্বনেইল বা অ্যাভাটার, সাবহেড টেক্সট, ডিভাইডার, এবং এমনকি বাটন ও আইকন। উদাহরণস্বরূপ, আমরা এইমাত্র যে কার্ডটি তৈরি করেছি, তাতে একটি LinearLayout মধ্যে দুটি TextView (একটি শিরোনামের জন্য এবং অন্যটি সেকেন্ডারি টেক্সটের জন্য) রয়েছে, যা কার্ডটির একেবারে নিচে অ্যালাইন করা আছে।

কার্ডগুলো সাধারণত অন্যান্য কার্ডের সাথে একটি সংগ্রহে দেখানো হয়। এই কোডল্যাবের পরবর্তী অংশে, আমরা সেগুলোকে একটি গ্রিডে সংগ্রহ হিসেবে সাজিয়ে রাখব।

৫. কার্ড দিয়ে একটি গ্রিড তৈরি করুন।

যখন একটি স্ক্রিনে একাধিক কার্ড থাকে, তখন সেগুলোকে এক বা একাধিক সংগ্রহে একত্রিত করা হয়। একটি গ্রিডের কার্ডগুলো সমতলীয় হয়, অর্থাৎ তাদের স্থির উচ্চতা একে অপরের সমান থাকে (যদি না সেগুলোকে তুলে নেওয়া বা টেনে নিয়ে যাওয়া হয়, কিন্তু আমরা এই কোডল্যাবে সে বিষয়টি আলোচনা করব না)।

তাসের গ্রিডটি সাজিয়ে নিন।

আমরা আপনাকে যে shr_product_card.xml ফাইলটি দিয়েছি, সেটি দেখুন:

shr_product_card.xml

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   app:cardBackgroundColor="@android:color/white"
   app:cardElevation="2dp"
   app:cardPreventCornerOverlap="true">

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:orientation="vertical">

       <com.android.volley.toolbox.NetworkImageView
           android:id="@+id/product_image"
           android:layout_width="match_parent"
           android:layout_height="@dimen/shr_product_card_image_height"
           android:background="?attr/colorPrimaryDark"
           android:scaleType="centerCrop" />

       <LinearLayout
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:orientation="vertical"
           android:padding="16dp">

           <TextView
               android:id="@+id/product_title"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:text="@string/shr_product_title"
               android:textAppearance="?attr/textAppearanceHeadline6" />

           <TextView
               android:id="@+id/product_price"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:text="@string/shr_product_description"
               android:textAppearance="?attr/textAppearanceBody2" />
       </LinearLayout>
   </LinearLayout>
</com.google.android.material.card.MaterialCardView>

এই কার্ড লেআউটটিতে একটি ছবিসহ কার্ড (এখানে একটি NetworkImageView , যা আমাদেরকে URL থেকে ছবি যুক্ত করার সুযোগ দেয়) এবং দুটি TextViews রয়েছে।

এরপর, আমরা আপনার জন্য যে ProductCardRecyclerViewAdapter দিয়েছি, সেটি দেখুন। এটি ProductGridFragment এর একই প্যাকেজে রয়েছে।

ProductCardRecyclerViewAdapter.java

package com.google.codelabs.mdc.java.shrine;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.google.codelabs.mdc.java.shrine.network.ImageRequester;
import com.google.codelabs.mdc.java.shrine.network.ProductEntry;

import java.util.List;

/**
* Adapter used to show a simple grid of products.
*/
public class ProductCardRecyclerViewAdapter extends RecyclerView.Adapter<ProductCardViewHolder> {

   private List<ProductEntry> productList;
   private ImageRequester imageRequester;

   ProductCardRecyclerViewAdapter(List<ProductEntry> productList) {
       this.productList = productList;
       imageRequester = ImageRequester.getInstance();
   }

   @NonNull
   @Override
   public ProductCardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
       View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.shr_product_card, parent, false);
       return new ProductCardViewHolder(layoutView);
   }

   @Override
   public void onBindViewHolder(@NonNull ProductCardViewHolder holder, int position) {
       // TODO: Put ViewHolder binding code here in MDC-102
   }

   @Override
   public int getItemCount() {
       return productList.size();
   }
}

উপরের অ্যাডাপ্টার ক্লাসটি আমাদের গ্রিডের বিষয়বস্তু পরিচালনা করে। প্রতিটি ভিউ তার প্রদত্ত বিষয়বস্তু নিয়ে কী করবে, তা নির্ধারণ করার জন্য আমরা শীঘ্রই onBindViewHolder() এর কোড লিখব।

একই প্যাকেজে আপনি ProductCardViewHolder ও দেখতে পারেন। এই ক্লাসটি সেই ভিউগুলোকে সংরক্ষণ করে যেগুলো আমাদের কার্ডের বিন্যাসকে প্রভাবিত করে, ফলে আমরা পরবর্তীতে সেগুলোকে পরিবর্তন করতে পারি।

ProductCardViewHolder.java

package com.google.codelabs.mdc.java.shrine;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;

public class ProductCardViewHolder extends RecyclerView.ViewHolder {

   public ProductCardViewHolder(@NonNull View itemView) {
       super(itemView);
       // TODO: Find and store views from itemView
   }
}

আমাদের গ্রিড সেট আপ করার জন্য, প্রথমে আমাদের shr_product_grid_fragment.xml থেকে প্লেসহোল্ডার MaterialCardView সরিয়ে ফেলতে হবে। এরপর, আপনাকে কার্ডের গ্রিডটির প্রতিনিধিত্বকারী কম্পোনেন্টটি যোগ করতে হবে। এক্ষেত্রে, আপনার shr_product_grid_fragment.xml ফাইলে AppBarLayout XML কম্পোনেন্টের নিচে একটি RecyclerView কম্পোনেন্ট যোগ করুন:

shr_product_grid_fragment.xml

<androidx.core.widget.NestedScrollView
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_marginTop="56dp"
   android:background="@color/productGridBackgroundColor"
   android:paddingStart="@dimen/shr_product_grid_spacing"
   android:paddingEnd="@dimen/shr_product_grid_spacing"
   app:layout_behavior="@string/appbar_scrolling_view_behavior">

   <androidx.recyclerview.widget.RecyclerView
       android:id="@+id/recycler_view"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />

</androidx.core.widget.NestedScrollView>

আপনার shr_product_grid_fragment.xml দেখতে নিম্নলিখিতের মতো হওয়া উচিত:

shr_product_grid_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".ProductGridFragment">

   <com.google.android.material.appbar.AppBarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content">

       <androidx.appcompat.widget.Toolbar
           android:id="@+id/app_bar"
           style="@style/Widget.Shrine.Toolbar"
           android:layout_width="match_parent"
           android:layout_height="?attr/actionBarSize"
           app:navigationIcon="@drawable/shr_menu"
           app:title="@string/shr_app_name" />
   </com.google.android.material.appbar.AppBarLayout>

   <androidx.core.widget.NestedScrollView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:layout_marginTop="56dp"
       android:background="@color/productGridBackgroundColor"
       android:paddingStart="@dimen/shr_product_grid_spacing"
       android:paddingEnd="@dimen/shr_product_grid_spacing"
       app:layout_behavior="@string/appbar_scrolling_view_behavior">

       <androidx.recyclerview.widget.RecyclerView
           android:id="@+id/recycler_view"
           android:layout_width="match_parent"
           android:layout_height="match_parent" />

   </androidx.core.widget.NestedScrollView>

</FrameLayout>

অবশেষে, onCreateView() ফাংশনে, setUpToolbar(view) কল করার পরে এবং return স্টেটমেন্টের আগে ` RecyclerView ইনিশিয়ালাইজেশন কোডটি ProductGridFragment.java ফাইলে যোগ করুন:

ProductGridFragment.java

@Override
public View onCreateView(
       @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
   ...
   setUpToolbar(view);

   // Set up the RecyclerView
   RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
   recyclerView.setHasFixedSize(true);
   recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2, GridLayoutManager.VERTICAL, false));
   ProductCardRecyclerViewAdapter adapter = new ProductCardRecyclerViewAdapter(
           ProductEntry.initProductEntryList(getResources()));
   recyclerView.setAdapter(adapter);
   int largePadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing);
   int smallPadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small);
   recyclerView.addItemDecoration(new ProductGridItemDecoration(largePadding, smallPadding));

   return view;
}

উপরের কোড স্নিপেটটিতে একটি RecyclerView সেট আপ করার জন্য প্রয়োজনীয় প্রারম্ভিক ধাপগুলো রয়েছে। এর মধ্যে RecyclerView এর লেআউট ম্যানেজার সেট করা এবং এর RecyclerView ইনিশিয়ালাইজ ও সেট করা অন্তর্ভুক্ত।

আপনার ProductGridFragment.java ফাইলটি এখন নিম্নরূপ দেখতে হবে:

ProductGridFragment.java

package com.google.codelabs.mdc.java.shrine;

import android.os.Bundle;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;


import com.google.codelabs.mdc.java.shrine.network.ProductEntry;

public class ProductGridFragment extends Fragment {

   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setHasOptionsMenu(true);
   }

   @Override
   public View onCreateView(
           @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
       // Inflate the layout for this fragment with the ProductGrid theme
       View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);

       // Set up the toolbar
       setUpToolbar(view);

       // Set up the RecyclerView
       RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
       recyclerView.setHasFixedSize(true);
       recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2, GridLayoutManager.VERTICAL, false));
       ProductCardRecyclerViewAdapter adapter = new ProductCardRecyclerViewAdapter(
               ProductEntry.initProductEntryList(getResources()));
       recyclerView.setAdapter(adapter);
       int largePadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing);
       int smallPadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small);
       recyclerView.addItemDecoration(new ProductGridItemDecoration(largePadding, smallPadding));

       return view;
   }

   private void setUpToolbar(View view) {
       Toolbar toolbar = view.findViewById(R.id.app_bar);
       AppCompatActivity activity = (AppCompatActivity) getActivity();
       if (activity != null) {
           activity.setSupportActionBar(toolbar);
       }
   }

   @Override
   public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
       menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
       super.onCreateOptionsMenu(menu, menuInflater);
   }

}

গড়ে তুলুন এবং পরিচালনা করুন।

f9aeab846fc3bb4c.png

কার্ডগুলো এখন সেখানে আছে! এগুলোতে এখনও কিছু দেখা যাচ্ছে না, তাই চলুন কিছু পণ্যের তথ্য যোগ করা যাক।

ছবি এবং লেখা যোগ করুন

প্রতিটি কার্ডের জন্য একটি ছবি, পণ্যের নাম এবং মূল্য যোগ করুন। আমাদের ViewHolder অ্যাবস্ট্রাকশনটি প্রতিটি কার্ডের ভিউগুলো ধারণ করে। আমাদের ViewHolder এ, নিম্নলিখিতভাবে তিনটি ভিউ যোগ করুন:

ProductCardViewHolder.java

package com.google.codelabs.mdc.java.shrine;

import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;

import com.android.volley.toolbox.NetworkImageView;

public class ProductCardViewHolder extends RecyclerView.ViewHolder {

   public NetworkImageView productImage;
   public TextView productTitle;
   public TextView productPrice;

   public ProductCardViewHolder(@NonNull View itemView) {
       super(itemView);
       productImage = itemView.findViewById(R.id.product_image);
       productTitle = itemView.findViewById(R.id.product_title);
       productPrice = itemView.findViewById(R.id.product_price);
   }
}

আমাদের RecyclerView এর অ্যাডাপ্টারে, ViewHolder, প্রতিটি ভিউ-এর তথ্য সেট করার জন্য onBindViewHolder() মেথডটি আপডেট করুন:

ProductCardRecyclerViewAdapter.java

@Override
public void onBindViewHolder(@NonNull ProductCardViewHolder holder, int position) {
   if (productList != null && position < productList.size()) {
       ProductEntry product = productList.get(position);
       holder.productTitle.setText(product.title);
       holder.productPrice.setText(product.price);
       imageRequester.setImageFromUrl(holder.productImage, product.url);
   }
}

উপরের কোডটি একটি ViewHolder ব্যবহার করে আমাদের RecyclerView এর অ্যাডাপ্টারকে বলে দেয় যে প্রতিটি কার্ডের সাথে কী করতে হবে।

এখানে এটি ViewHolder এর প্রতিটি TextView তে টেক্সট ডেটা সেট করে এবং একটি URL থেকে ছবি পাওয়ার জন্য ImageRequester কে কল করে। ImageRequester হলো একটি ক্লাস যা আমরা আপনার সুবিধার জন্য দিয়েছি এবং এটি Volley লাইব্রেরি ব্যবহার করে (এটি এই কোডল্যাবের আওতার বাইরের একটি বিষয়, তবে আপনি নিজে থেকে কোডটি অন্বেষণ করতে পারেন)।

নির্মাণ ও পরিচালনা:

249db074eff043f4.png

আমাদের পণ্যগুলো এখন অ্যাপে দেখা যাচ্ছে!

৬. পুনরালোচনা

আমাদের অ্যাপটির একটি সাধারণ কার্যপ্রণালী রয়েছে, যা ব্যবহারকারীকে লগইন স্ক্রিন থেকে হোম স্ক্রিনে নিয়ে যায়, যেখানে পণ্যগুলো দেখা যায়। মাত্র কয়েকটি কোডের লাইনে, আমরা একটি শিরোনাম ও তিনটি বাটনসহ একটি টপ অ্যাপ বার এবং আমাদের অ্যাপের বিষয়বস্তু উপস্থাপনের জন্য কার্ডের একটি গ্রিড যুক্ত করেছি। আমাদের হোম স্ক্রিনটি এখন একটি সাধারণ কাঠামো এবং ব্যবহারযোগ্য বিষয়বস্তুসহ সহজ ও কার্যকরী।

পরবর্তী পদক্ষেপ

টপ অ্যাপ বার, কার্ড, টেক্সট ফিল্ড এবং বাটনের মাধ্যমে, আমরা এখন MDC-Android লাইব্রেরি থেকে চারটি মূল ম্যাটেরিয়াল ডিজাইন কম্পোনেন্ট ব্যবহার করেছি! আপনি MDC Android-এর MDC-Android ক্যাটালগ কম্পোনেন্টসে আরও অনেক কম্পোনেন্ট অন্বেষণ করতে পারেন।

যদিও আমাদের অ্যাপটি সম্পূর্ণরূপে কার্যকরী, এটি এখনও কোনো নির্দিষ্ট ব্র্যান্ডকে প্রকাশ করে না। MDC-103: Material Design Theming with Color, Shape, Elevation and Type কোর্সে, আমরা একটি প্রাণবন্ত ও আধুনিক ব্র্যান্ড ফুটিয়ে তোলার জন্য এই উপাদানগুলোর স্টাইল কাস্টমাইজ করব।

আমি যুক্তিসঙ্গত সময় ও শ্রম দিয়ে এই কোডল্যাবটি সম্পন্ন করতে পেরেছি।

দৃঢ়ভাবে একমত একমত নিরপেক্ষ দ্বিমত তীব্রভাবে দ্বিমত পোষণ করি।

আমি ভবিষ্যতে ম্যাটেরিয়াল কম্পোনেন্টস ব্যবহার করা চালিয়ে যেতে চাই।

দৃঢ়ভাবে একমত একমত নিরপেক্ষ দ্বিমত তীব্রভাবে দ্বিমত পোষণ করি।