Android

Android Navigation Drawer ile Slide Menü – 3

Selamlar herkese, serinin üçüncü yazısında menümüze son özelliklerini vereceğiz. Ve artık bu yazıyla menü serisini sonlandırmış olacağız. Şimdi gelelim meselemize. Buraya kadar menüyü oluşturup, sayfalar ekledik. Şimdi ise ufak bir özellik daha ekleyip, performans amaçlı bir ipucu ile bitirmiş olacağız.

İlk olarak menü öğelerine tıklanıldığında arkaplanlarının değişmesi özelliğini ekleyelim. Bunun için menü öğelerine normal hali ve basılı hali için birer arkaplan tasarlamamız gerekiyor. Öğenin normal hali için aşağıdaki dosyayı res–> drawable klasörünün altında oluşturuyoruz.

menu_item_normal.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#3a3a3a" />
</shape>

Basılı hali için aşağıdaki dosyayı oluşturuyoruz.

menu_item_pressed.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#BD1E13" />
</shape>

Uygulamanın hangi arkaplanı seçeceğini anlaması için bir selector dosyasına ihtiyacımız var. Yine drawable klasörünün altında aşağıdaki dosyayı oluşturuyoruz.

menu_item_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/menu_item_pressed" android:state_pressed="true"></item>
</selector>

Daha önce hazırladığımız activity_main.xml dosyasının içindeki listview içine listSelector özelliğini ekliyoruz ve menu_item_bg.xml dosyasını selector olarak atıyoruz.

activity_main.xml

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.gkhnl.slidingmenuinandroid.MainActivity">

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <ListView
        android:id="@+id/lw_Menu"
        android:layout_width="250dp"
        android:layout_height="match_parent"
        android:choiceMode="singleChoice"
        android:layout_gravity="left|start"
        android:listSelector="@drawable/menu_item_bg"
        android:background="@color/list_back" />

</android.support.v4.widget.DrawerLayout>

Son olarak menü öğelerinin tasarımını yaptığımız slidemenu_item.xml dosyasındaki arkaplanı @drawable/menu_item_bg olarak değiştiriyoruz.

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:paddingBottom="10dp"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:paddingTop="10dp">

        <ImageView
            android:id="@+id/img_icon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:src="@drawable/facebook" />

        <TextView
            android:id="@+id/txt_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:text="AAA"
            android:textColor="@color/title"
            android:textSize="16sp" />

    </LinearLayout>

</LinearLayout>

Buraya kadar her şey tamam. Şimdi son bir özellikten daha bahsedelim. Menü öğelerimizin arasında bulunan çizgiler yani divider özelliği eğer custom listview tasarlarsanız kaybolabiliyor veya biz kendi istediğimiz gibi renk vermek isteyebiliyoruz.

device-2013-01-24-130601

Bunu yapmak için listview içerisinde bulunan divider özelliğini kullanacağız. activity_main.xml dosyamızı açıp aşağıdaki gibi güncelliyoruz.

activity_main.xml

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.gkhnl.slidingmenuinandroid.MainActivity">

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <ListView
        android:id="@+id/lw_Menu"
        android:layout_width="250dp"
        android:layout_height="match_parent"
        android:choiceMode="singleChoice"
        android:divider="@color/divider"
        android:dividerHeight="1dp"
        android:layout_gravity="left|start"
        android:listSelector="@drawable/menu_item_bg"
        android:background="@color/list_back" />

</android.support.v4.widget.DrawerLayout>

Renk dosyamızı da aşağıdaki gibi güncelleyelim.

color.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="list_back">#ff3a3a3a</color>
    <color name="title">#fff</color>
    <color name="divider">#2B2B2B</color>
</resources>

Görsel olarak bir menüye verebileceğimiz en temel yetenekleri kazandırmış olduk. Son olarak aslında sadece menü ile alakalı olmayan, hatta menüde kullanılması zorunlu olmayan bir yapıdan bahsedelim. Bahsettiğim yapı “ViewHolder” tasarım deseni. Peki nedir ViewHolder?

ViewHolder tasarım deseni listview’e verinin yüklenmesi sırasında, yüklenme hızını artırmak için kullanılıyor.  Bunu nasıl sağlıyor diye sorarsak basitçe şöyle anlatabiliriz; Listview için her item yükleneceği sırada findViewById() ile bileşenleri yani view çağrılıp ve içine veriler yükleniyor ve ekrana basılıyor. Elimizde ne kadar veri varsa her seferinde bu işlem gerçekleşiyor. Bu durum elimizde binlerce veri olduğunda sıkıntı oluşturuyor ve performans kaybı yaşıyoruz. ViewHolder burada devreye giriyor ve her seferinde yeni bir view oluşturması yerine, eski view tekrar kullanılıyor ve veriler yüklenip ekrana basılıyor. Bu sayede ram şişmesi gibi bir problemden de kurtulmuş oluyoruz. Ancak burada şunu belirtmeliyim bizim menümüz veya yapacağınız 10 – 15 öğeli bir menü için bu yapı gözle görülür bir performans artışı sağlamaz. Bu yapıyı hem diğer listview yapılarınızda hem de material design menü de kullanacığımız için tanıtmak istedim.

ViewHolder desenini Adapter dosyamızın içine yerleştirelim.

SlideMenuAdapter.java

package com.gkhnl.slidingmenuinandroid;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

/**
 * Created by gkhnnl on 11/06/15.
 */
public class SlideMenuAdapter extends BaseAdapter {

    private List<SlideMenuItem> items;
    private Context ctx;

    public SlideMenuAdapter(List<SlideMenuItem> items, Context context) {
        this.items = items;
        this.ctx = context;
    }

    // Mevcut item sayısını verir
    @Override
    public int getCount() {
        return items.size();
    }

    // Position ı verilen item ı verir
    @Override
    public Object getItem(int position) {
        return items.get(position);
    }

    // Item position ı verir
    @Override
    public long getItemId(int position) {
        return position;
    }

    // Custom view yükler
    @Override
    public View getView(int position, View view, ViewGroup viewGroup) {

        ViewHolder holder = null;

        // Her list item için custom tasarım yüklüyor
        if (view == null) {

            holder = new ViewHolder();

            view = LayoutInflater.from(ctx).inflate(R.layout.slidemenu_item, null);

            // Yeni tasarım içindeki title textine ulaşıp, veriyi set ediyor
            holder.txt_title = (TextView) view.findViewById(R.id.txt_title);
            holder.img_icon = (ImageView) view.findViewById(R.id.img_icon);

            holder.txt_title.setText(items.get(position).getTitle());
            holder.img_icon.setImageResource(items.get(position).getIcon());

            view.setTag(holder);

        } else {
            holder = (ViewHolder) view.getTag();
        }

        return view;
    }

    static class ViewHolder {

        public TextView txt_title;
        public ImageView img_icon;
    }
}

Öncelikle statik bir ViewHolder sınıfı oluşturuyor ve bileşenlerimizi burada tanımlıyoruz. holder nesnemizi tanımlayıp bileşenleri bu nesne üzerinden çağırıp, oluşturuyoruz. Burada setTag() metodunu var olan holder nesnesini kontrol etmek için kullanıyoruz.

Menü yazılarımızın sonuna geldik. Tüm sorularınızı ve önerilerinizi buradan beklerim.

Ekran Görüntüleri

Fullscreen_27_06_15_18_59

Kaynak Kodlar

Projenin tümüne GitHub dan ulaşabilirisiniz.

Bir sonraki yazıda görüşmek üzere 🙂

 

Önceki Yazı

Android Navigation Drawer ile Slide Menü – 2

1 Yorum

  • Merhaba,
    Bir tane sol bir tane sağ ekleniyor peki sol tarafa 2 adet slider menu eklemek mümkün mü?

mkatr34 için bir yanıt yazın X