آموزش برنامه نویسی Android قسمت هشتم: ساخت لیست با ListView

نوشته شده توسط:
قسمت های دیگر این مطلب:

در این قسمت قصد داریم به مبحث مهم ساخت ListView بپردازیم. با هیتوس همراه باشید.

در تصویر بالا چند نمونه List در نرم افزارهای معروف را می‌بینید.

آشنایی با ScrollView ها

یک لایه نمایشی در اندروید به نام ScrollView وجود دارد که عملکرد به ظاهر مشابهی با ListView دارد.

طرز کار ScrollView به این شکل است که درون آن یک LinearLayout ایجاد می‌گردد و اطلاعات در صورتی که بیشتر از طول صفحه باشند به حالت اسکرول نمایش داده می‌شوند.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="fill_parent">

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

        <Button
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:text="Button" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:text="Button" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:text="Button" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:text="Button" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:text="Button" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:text="Button" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:text="Button" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:text="Button" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:text="Button" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:text="Button" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:text="Button" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="140dp"
            android:text="Button" />
    </LinearLayout>
</ScrollView>

در بالا 12 عدد Button درون LinearLayout ایجاد می‌کنیم.

نتیجه اجرا مانند زیر خواهد بود:

ListView چیست و چگونه ایجاد می‌شود

هر چند که لیست‌ها را با ScrollView نیز می‌توان ایجاد کرد ولی در برخی حالات استفاده از ScrollView کاری بسیار اشتباه است. اساسا هر گونه لیست با آیتم‌های هم شکل مانند شماره مخاطبان و یا لیست فیلم و یا آهنگ را باید با ListView ایجاد کرد.

در ابتدا در activity_main پروژه یک ListView با شناسه listView ایجاد می‌کنیم. سورس activity_main.xml را در پایین ببینید:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="hitos.ir.hitosapp.MainActivity">
    
    <ListView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/listView"
        />
</RelativeLayout>

ListView متشکل از چندین آیتم پشت سر هم است بنابراین ابتدا باید یک آیتم را طراحی کنیم تا ما بقی آیتم‌ها از روی این آیتم ساخته شوند. برای این کار در ابتدا روی layout موجود در پوشه res راست کلیک کرده و از New گزینه New resource file را انتخاب می‌کنیم. در باکس File name نامی برای این فایل باید وارد شود که ما listview_items را می‌نویسیم. پس در listview_items قصد داریم یک نمونه از آیتم‌هایی که در آینده قرار است لیست شوند بسازیم.

هر آیتم یک لیست می‌تواند شامل چند شی از قبیل نوشته، عکس و یا کلید باشد.

مثلا در تصویر فوق هر آیتم شامل یک عکس نشان دهنده وضعیت آب و هوا، نوشته نام منطقه، نوشته وضعیت آب و هوا، درجه حرارت و فلش موجود در سمت راست آیتم.

پس از باز کردن فایل جدید listview_items.xml درون LinearLayout موجود در آن یک آیتم را اضافه می‌کنیم. در این مثال قصد داریم تنها یک TextView را اضافه کنیم:

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

        <TextView
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           android:text="New Text"
           android:id="@+id/listItem"
           android:textColor="#000000"
           android:padding="10dip"/>

</LinearLayout>

در سطرهای هشت و نه برای TextView مقدار layout_width را برابر fill_parent قرار دادیم تا کل عرض صفحه را اشغال کند و مقدار layout_height نیز برابر wrap_content است.

در سطر 11 یک شناسه id با نام listItem را به TextView اختصاص دادیم.

در سطرهای 12 و 13 نیز به ترتیب برای TextView رنگ مشکلی و فاصله padding را تعیین کردیم.

نتیجه طراحی این یک آیتم به صورت ساده زیر است:

حال نوبت کار با Activity رسیده است، برای ساخت آیتم‌های موجود در ListView قصد داریم یک آرایه ایجاد کنیم و هر آیتم را از درون آرایه صدا بزنیم.

یک آرایه در سطح کلاس ایجاد کرده و درون onCreate آن را مقدار دهی می‌کنیم.

public class MainActivity extends AppCompatActivity {

  String[] list_items;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    list_items= new String[]{
      "item1", "item2", "item3", "item4", "item5"
    };
  }
}

برای ساخت لیست خود باید از Adapter‌ها استفاده کرد و یک کلاس نمونه را از کلاس BaseAdapter اندروید extends کنیم. کلاس را زیر را زیر متد onCreate ایجاد می‌کنیم:

  private class myAdapter extends BaseAdapter{   
  }

وقتی کلاس myAdapter را ایجاد کنید دور سطر کلاس یک خط قرمز ایجاد می‌شود که نشان دهنده این است که این کلاس نیازمند چندین متد است که الزما باید به این کلاس اضافه شوند. کلیدهای Alt + Enter را فشار داده و با انتخاب Implement methods و تایید صفحه باز شده متدهای ضروری به برنامه اضافه می‌شوند. نحوه ویرایش متدها و اضافه کردن موارد ضروری در زیر به صورت کامل آمده است:

  private class myAdapter extends BaseAdapter{

    @Override
    public int getCount() {
      return 0;
    }

    @Override
    public Object getItem(int position) {
      return null;
    }

    @Override
    public long getItemId(int position) {
      return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      return null;
    }
  }

متد getCount تعداد آیتم‌های ListView را ارائه می‌دهد.

متد getItem مکان و یا شماره آیتم فعلی را می‌دهد.

نکته: شمارش آیتم‌های آرایه از صفر شروع می‌شود.

متد getItemId شناسه و یا ID هر آیتم را بر می‌گرداند که در اینجا همان شماره آیتم است.

متد getView برای نمایش دادن آیتم‌های ListView مورد استفاده قرار می‌گیرد و همانطور که از ساختار متد می‌بینید خروجی آن نیز view است.

توجه کنید که کلاس فوق به یک LayoutInflater و یک سازنده نیز نیاز دارد. وظیفه LayoutInflater ساختن تک تک آیتم‌های ListView است.

سازنده و یا Contractor نیز برای مقدار دهی به LayoutInflater مورد استفاده قرار می‌گیرد.

کلاس myAdapter زیر به صورت کامل برنامه نویسی شده است و در زیر کدها به تشریح تمام دستورهای موجود می‌پردازیم:

  private class myAdapter extends BaseAdapter{

    private LayoutInflater myInflater;

    public myAdapter(Context context){
      myInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
      return list_items.length;
    }

    @Override
    public Object getItem(int position) {
      return position;
    }

    @Override
    public long getItemId(int position) {
      return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      View viewitem;
      if(convertView == null){
        viewitem = myInflater.inflate(R.layout.listview_items, null);
      }else{
        viewitem = convertView;
      }

      TextView textView= (TextView) viewitem.findViewById(R.id.listItem);
      textView.setText(list_items[position]);

      return viewitem;
    }
  }

در سطر سوم myInflater را از روی LayoutInflater ساختیم.

در سطر پنجم یک سازنده ایجاد کردیم که تا myInflater را فراخوانی کند.

در سطر دهم متد getCount قرار گرفته است که با return کردن دستور list_items.length تعداد اعضای آرایه را از متد خارج می‌کنیم.

در سطر 15 و در متد getItem یک ورودی به نام position داریم که همین ورودی را به عنوان خروجی با return از متد خارج می‌کنیم.

در سطر 20 نیز متد getItemId با return کردن position کار را خاتمه می‌دهد.

در سطر 25 متد getView وظیفه ساختن هر آیتم با TextView را بر عهده دارد. این متد سه ورودی دارد، اول position که آیتم جاری است، دوم convertView که view جاری که در حال ساخت آن هستیم و ViewGroup که مجموعه تمام آیتم‌ها را در بر می‌گیرد. خروجی این متد View است بنابراین برای اولین کار یک متغیر از نوع View می‌سازیم و نام آن را viewitem می‌گذاریم.

در سطر 27 تا 31 بررسی می‌کنیم هر آیتم اگر view نداشت با myInflater و اتصال لایه نمایش listview_items به آن یک view ایجاد می‌کنیم. اگر نیز convertView موجود بود تنها آن را برابر viewitem قرار می‌دهیم.

در سطر 33 یک TextView ایجاد می‌کنیم و آن را با شناسه id از لایه نمایش listview_items مشتق می‌کنیم. در این جا findViewById را به viewitem متصل کردیم تا عمل جستجو از viewitem معرفی شده در بالا انجام گیرد.

در سطر 34 textview تعریف شده در سطر قبل را با setText و یکی از مقادیر آرایه و position مقدار دهی می‌کنیم.

در نهایت و در سطر 36 با return این viewitem را خارج می‌کنیم.

حال برای آخرین کار باید این myAdapter ایجاد شده در مرحله قبل را در onCreate فراخوانی کنیم تا به محض اجرا شدن برنامه این لیست ساخته شود. در onCreate از دستورات زیر استفاده می‌کنیم:

    myAdapter myNewAdapter = new myAdapter(getApplicationContext());
    ListView listView = (ListView) findViewById(R.id.listView);
    listView.setAdapter(myNewAdapter);

در سطر اول myNewAdapter را از myAdapter ایجاد شده در مراحل قبل ایجاد کردیم.

در سطر دوم ListView را با شناسه id به listView نسبت دادیم.

در سطر سوم listView ایجاد شده در سطر قبل را با متد setAdapter و با ورودی myNewAdapter مقدار دهی کردیم.

در پایین کل سورس MainActivity را به صورت یک جا ببینید:

public class MainActivity extends AppCompatActivity {

  String[] list_items;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    list_items= new String[]{
      "item1", "item2", "item3", "item4", "item5"
    };

    myAdapter myNewAdapter = new myAdapter(getApplicationContext());
    ListView listView = (ListView) findViewById(R.id.listView);
    listView.setAdapter(myNewAdapter);
  }

  private class myAdapter extends BaseAdapter{

    private LayoutInflater myInflater;

    public myAdapter(Context context){
      myInflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
      return list_items.length;
    }

    @Override
    public Object getItem(int position) {
      return position;
    }

    @Override
    public long getItemId(int position) {
      return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      View viewitem;
      if(convertView == null){
        viewitem = myInflater.inflate(R.layout.listview_items, null);
      }else{
        viewitem = convertView;
      }

      TextView textView= (TextView) viewitem.findViewById(R.id.listItem);
      textView.setText(list_items[position]);

      return viewitem;
    }
  }
}

نتیجه اجرای کدهای فوق مانند زیر خواهد بود:

توجه داشته باشید که در دوره طراحی رابط کاربری اندروید با RecyclerView‌ها که نسل جدید ListView‌ها هستند آشنا خواهید شد.

در ادامه با هیتوس همراه باشید.

تگ ها: android / اندروید
نظر خود را برای این مطلب وارد کنید
دریافت خبرنامه

موضوعات بخش برنامه نویسی و نرم افزار

مطالب برگزیده برنامه نویسی اندروید

مطالب برگزیده سایت