-->

[Android / Java]

ListView 특정 아이템 클릭 막기

 * 목표 : ListView안에 특정 아이템을 클릭했을 때 클릭 이벤트가 발생하지 않도록 막아보자.

 

ListView를 사용할 때는 조회성이 아니라면 보통 클릭 리스너를 만들어준다. 조회성이어도 만들어주는 것이 대부분. 

ListView내에 아이템을 전부 클릭하게 할 수도 못 하게 할 수도 있다.

그러나 어떠한 환경에서는 특정 ListView 아이템만 클릭을 막아야 하는 상황도 벌어진다. 

예를 들면 내가 만들었던 NavigationDrawer를 한번 살펴보자.

 

화면을 Swipe 혹은 햄버거 버튼 클릭 시 등장하는 NavigationDrawer 이다. 요거 적용하는 것은 다음 시간에 해보는 것으로 하고...

아무튼 이미지를 살펴보면 하얀색 텍스트의 대메뉴가 있고 연한 하늘색의 소메뉴 항목이 존재한다. 

디자이너에게 디자인 레이아웃을 처음 받았을 때 이 부분을 어떻게 구현할지 고민을 했다. 

개발단계에서 메뉴는 특정 상황에서 추가되거나 삭제 혹은 메뉴명이 변경될 수도 있기 때문에 비교적 수정이 수월한 형태로 만들어야 했다. 

메뉴의 Depth를 정하고 그에 따라 텍스트의 크기와 색상, 첨부한 이미지가 반영되도록 했다.

 

그런데 요건에 흰색 텍스트는 클릭을 원하지 않는다고 했다. 그래서 Depth 1은 클릭 자체를 막는 방법을 찾아보았다.

import java.util.ArrayList;

import android.annotation.SuppressLint;
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.LinearLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;

import com.m3s.skylark.R;
import com.m3s.skylark.main.drawer.DrawerItem;

public class CustomDrawerAdapter extends BaseAdapter {

    private static final String TAG = "CustomDrawerAdapter";
    private Context mContext;
    private ArrayList<DrawerItem> drawerItems;

    public CustomDrawerAdapter(Context mContext, ArrayList<DrawerItem> drawerItems) {
        this.mContext = mContext;
        this.drawerItems = drawerItems;
    }

    @SuppressLint("ResourceAsColor")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder viewHolder;

        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.custom_drawer_item, parent, false);

            viewHolder = new ViewHolder();

            viewHolder.ItemLayout = convertView.findViewById(R.id.itemLayout);
            viewHolder.ItemName = convertView.findViewById(R.id.drawer_itemName);
            viewHolder.icon = convertView.findViewById(R.id.drawer_icon);

            convertView.setTag(viewHolder);

        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        DrawerItem drawerItem = drawerItems.get(position);

        viewHolder.ItemName.setText(drawerItem.getItemName());

        if (drawerItem.getCategory().equals("MAIN")) { //Main이면 set Title icon
            viewHolder.icon.setImageDrawable(ResourcesCompat.getDrawable(convertView.getResources(), drawerItem.getImgResID(), null));
            viewHolder.ItemName.setTextColor(ContextCompat.getColor(mContext, R.color.white));
            viewHolder.ItemName.setTextSize(16);

        } else if (drawerItem.getCategory().equals("SUB")) { //SUB 니까 ICON 없어도 됨.
            viewHolder.icon.setImageDrawable(null);
            viewHolder.ItemName.setTextColor(ContextCompat.getColor(mContext, R.color.navi_item_click));
            viewHolder.ItemName.setTextSize(14);
        }

        isEnabled(position);

        return convertView;
    }

    @Override
    public int getCount() {
        return drawerItems.size();
    }

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

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

    @Override
    public boolean isEnabled(int position) {
        if (!drawerItems.get(position).isClickable()) { //Clickable 여부에 따라서
            return false;
        } else {
            return true;
        }
    }

    private static class ViewHolder {
        LinearLayout ItemLayout;
        TextView ItemName;
        ImageView icon;
    }

    public void addItem(String categoryName, int imgResID, boolean clickable, @Nullable String[] subTitle) {
        DrawerItem item = new DrawerItem();

        item.setItemName(categoryName);
        item.setImgResID(imgResID);
        item.setClickable(clickable);
        item.setCategory("MAIN");

        drawerItems.add(item);

        if (subTitle != null) {
            for (int i = 0; i < subTitle.length; i++) {
                DrawerItem subItem = new DrawerItem();
                subItem.setItemName(subTitle[i]);
                subItem.setClickable(true);
                subItem.setCategory("SUB");

                drawerItems.add(subItem);
            }
        }
    }

}

 

방법은 아~주 간단하다. isEnabled(int position) 메소드를 Overide 하면 된다.

따라서 나는 해당 모델클래스에 boolean 값을 하나 추가했고 그에 따라 return 값을 지정해주어 해결됐다.

public class DrawerItem {

    private String ItemName;
    private int imgResID;
    private String category;
    private boolean isClickable;

    public DrawerItem() { }

    public String getItemName() {
        return ItemName;
    }
    public void setItemName(String itemName) {
        ItemName = itemName;
    }

    public int getImgResID() {
        return imgResID;
    }
    public void setImgResID(int imgResID) {
        this.imgResID = imgResID;
    }

    public String getCategory() { return category; }
    public void setCategory(String category) { this.category = category; }

    public boolean isClickable() { return isClickable; }
    public void setClickable(boolean clickable) { this.isClickable = clickable; }

    @Override
    public String toString(){
        return "DrawerItem [ ItemName=" + ItemName +
                ", imgResID=" + imgResID +
                ", category=" + category +
                ", clickable=" + isClickable +
                " ]";
    }

}

 

+ Recent posts