안드로이드 리스트뷰 아이템 정렬하기 2. (Android ListView Item Sorting 2) [Example]

2016. 9. 19. 15:08


1. ListView 아이템 다루기

초보 개발자들이, 처음 안드로이드 ListView를 다룰 때 어려워하는 것 중 하나가 바로, Adapter의 개념 및 사용 방법에 대한 이해입니다. TextView, ImageView, Button 등을 사용할 때 경험할 수 있었던 "구현의 단순함"이나, "실행 결과의 직관성" 같은 것들이, ListView의 Adapter를 접하는 순간, "익숙하지 않은 생소함" 또는 "구조의 복잡성"으로 바뀌어 버리니까요.


하지만 대부분의 개발 관련 지식과 기술이 그러하듯, Adapter 또한, 지속적으로 학습하고 반복적으로 사용하는 과정을 거치면, 금방 능숙하게 사용할 수 있게 됩니다. 게다가 Adapter를 사용함으로써 누릴 수 있는 여러 장점들은, 개발에 소요되는 노력과 시간을 상당 부분 줄일 수 있게 만들어주죠.


그러한 Adapter의 장점을 크게 누릴 수 있는 경우가 바로, ListView의 아이템을 정렬하는 기능을 구현하는 경우입니다.
Adapter를 중심으로, 내부적으로 관리되는 데이터와 화면에 표시되는 View 영역이 분리됨으로써, 아이템 정렬에 필요한 코드의 양이나, 고려되어야 할 예외처리들이 줄어드는 효과를 볼 수 있게 되는 것이죠.


이러한 Adapter의 장점에 더하여 [안드로이드 리스트뷰 아이템 정렬하기 1]에서 살펴본 것과 같이, Comparator 인터페이스와 Collections 클래스의 조합으로 구현할 수 있는 리스트 정렬 기능은 ListView 아이템을 정렬하는 과정을 한층 더 간편하게 만들어 줍니다. 데이터 정렬을 위한 루프 실행이나 복잡한 알고리즘에 대한 고민없이, 데이터 순서의 기준이 되는 조건을 기술하는 것만으로 데이터가 정렬된 리스트를 획득할 수 있으니까요.


이제, [안드로이드 리스트뷰 아이템 정렬하기 1]에서 설명한 내용을 바탕으로, ListView의 아이템을 정렬하는 예제를 작성해보도록 하겠습니다.

2. ListView 아이템 정렬하기.

예제의 Layout은 두 개의 TextView로 구성되는 Custom ListView와 각 TextView를 오름차순, 내림차순으로 정렬하는 네 개의 Button들을 포함합니다.

리스트뷰 정렬 예제 구성도


2.1 워크플로우

리스트뷰 아이템 정렬 워크플로우


2.2 MainActivity의 Layout 구성.

앞서 설계한 화면 구성 내용에 맞게 MainActivity의 Layout XML을 "activity_main.xml" 파일(또는 "content_main.xml")에 작성합니다.

[STEP-1] "activity_main.xml" - MainActivity의 Layout 구성.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.recipes4dev.examples.listviewitemsorting.MainActivity"
    tools:showIn="@layout/activity_main">

    <ListView
        android:id="@+id/listview1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true">

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/buttonNoAsc"
            android:text="No ASC"/>

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/buttonNoDesc"
            android:text="No DESC"/>

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/buttonTextAsc"
            android:text="Text ASC"/>

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/buttonTextDesc"
            android:text="Text DESC"/>

    </LinearLayout>

</RelativeLayout>

2.3 ListView 아이템에 대한 Layout 구성.

다음으로, Custom ListView를 만들 때 필요한, ListView 아이템의 Layout 구성 작업을 수행합니다. 아이템의 Layout은 "listview_item.xml" 이라는 이름으로 작성합니다.

[STEP-2] "listview_item.xml" - ListView 아이템 Layout 구성.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        android:gravity="center"
        android:layout_weight="1"
        android:id="@+id/textViewNo"/>

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        android:layout_weight="4"
        android:id="@+id/textViewText"/>

</LinearLayout>

2.4 ListView 아이템 데이터 클래스 정의.

ListView 아이템을 위한 클래스를 정의합니다. 아이템은 "No"와 "Text"라는 두 개의 TextView로 구성되어 있지만, "No"는 숫자 값을 사용하여 표현할 것이므로 클래스에는 int와 String 변수 하나씩 정의합니다.

[STEP-3] "ListViewItem.java" - ListView 아이템 데이터 클래스 정의.
public class ListViewItem {
    private int no ;
    private String text ;

    public void setNo(int no) {
        this.no = no ;
    }
    public void setText(String text) {
        this.text = text ;
    }

    public int getNo() {
        return no ;
    }
    public String getText() {
        return text ;
    }
}

2.5 ListView Adapter 구현.

이전에 작성했던 Custom ListView 예제들과 마찬가지로, 위에서 정의한 아이템 데이터와 View를 연결하는 Adapter를 구현합니다.

[STEP-4] "ListViewAdapter.java" - Custom Adapter 구현.
public class ListViewAdapter extends BaseAdapter {
    // Adapter에 추가된 데이터를 저장하기 위한 ArrayList
    private ArrayList<ListViewItem> listViewItemList ;

    // ListViewAdapter의 생성자
    public ListViewAdapter(ArrayList<ListViewItem> itemList) {
        if (itemList == null) {
            listViewItemList = new ArrayList<ListViewItem>() ;
        } else {
            listViewItemList = itemList ;
        }
    }

    // Adapter에 사용되는 데이터의 개수를 리턴. : 필수 구현
    @Override
    public int getCount() {
        return listViewItemList.size() ;
    }

    // position에 위치한 데이터를 화면에 출력하는데 사용될 View를 리턴. : 필수 구현
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final int pos = position;
        final Context context = parent.getContext();

        // "listview_item" Layout을 inflate하여 convertView 참조 획득.
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.listview_item, parent, false);
        }

        // 화면에 표시될 View(Layout이 inflate된)으로부터 위젯에 대한 참조 획득
        TextView noTextView = (TextView) convertView.findViewById(R.id.textViewNo) ;
        TextView textTextView = (TextView) convertView.findViewById(R.id.textViewText) ;

        // Data Set(listViewItemList)에서 position에 위치한 데이터 참조 획득
        ListViewItem listViewItem = listViewItemList.get(position);

        // 아이템 내 각 위젯에 데이터 반영
        noTextView.setText(Integer.toString(listViewItem.getNo()));
        textTextView.setText(listViewItem.getText());

        return convertView;
    }

    // 지정한 위치(position)에 있는 데이터와 관계된 아이템(row)의 ID를 리턴. : 필수 구현
    @Override
    public long getItemId(int position) {
        return position ;
    }

    // 지정한 위치(position)에 있는 데이터 리턴 : 필수 구현
    @Override
    public Object getItem(int position) {
        return listViewItemList.get(position) ;
    }

    // 아이템 데이터 추가를 위한 함수. 개발자가 원하는대로 작성 가능.
    public void addItem(int no, String text) {
        ListViewItem item = new ListViewItem();

        item.setNo(no);
        item.setText(text);

        listViewItemList.add(item);
    }

    public ArrayList<ListViewItem> getItemList() {
        return listViewItemList ;
    }
}

2.6 Adapter 생성 후 ListView에 연결.

Adapter를 구현했으니, Adapter 객체를 하나 생성하고 ListView에 지정하는 코드를 작성합니다.

[STEP-5] "MainActivity.java" - onCreate() 함수에서 Adapter 생성 후 ListView에 연결.
public class MainActivity extends AppCompatActivity {
    ListView listview ;
    ListViewAdapter adapter;

    ArrayList<ListViewItem> itemList = new ArrayList<ListViewItem>() ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // ... 코드 계속

        // Adapter 생성
        adapter = new ListViewAdapter(itemList) ;

        // 리스트뷰 참조 및 Adapter달기
        listview = (ListView) findViewById(R.id.listview1);
        listview.setAdapter(adapter);

        // 코드 계속 ...
    }
}

2.7 데이터 추가.

이제, ListView 아이템 데이터를 추가합니다. 정렬된 결과와 식별이 잘 되도록, 초기 입력 데이터는 순서가 섞이도록 입력합니다.

[STEP-6] "MainActivity.java" - 데이터 추가.
public class MainActivity extends AppCompatActivity {

    // ... 코드 계속

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // ... 코드 계속

        // 아이템 추가.
        adapter.addItem(4, "John Smith") ;
        adapter.addItem(2, "Micheal Jacson") ;
        adapter.addItem(3, "Eric Clapton") ;
        adapter.addItem(1, "Beatles") ;
        adapter.addItem(5, "Queen") ;
    }
}

2.8 Button 이벤트에 따라 정렬 기능 구현.

마지막으로, 이 글의 핵심인 ListView 아이템을 정렬하는 코드를 작성하겠습니다.
예제 Layout 구성도에서 본 대로, Button들이 클릭될 때, No 및 Text 항목에 대해 오름차순 또는 내림차순으로 정렬을 수행하도록 만듭니다.


먼저, "No ASC" Button 클릭 시, "No" 항목에 대해 오름차순으로 정렬되도록 작성한 코드입니다. 낮은 숫자(1)부터 높은 숫자(5) 순으로 화면에 표시됩니다.

[STEP-7.1] "MainActivity.java" - "No ASC" 클릭 시, "No" 항목에 대한 오름차순 정렬.
        Button buttonNoAsc = (Button) findViewById(R.id.buttonNoAsc) ;
        buttonNoAsc.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                Comparator<ListViewItem> noAsc = new Comparator<ListViewItem>() {
                    @Override
                    public int compare(ListViewItem item1, ListViewItem item2) {
                        int ret ;

                        if (item1.getNo() < item2.getNo())
                            ret = -1 ;
                        else if (item1.getNo() == item2.getNo())
                            ret = 0 ;
                        else
                            ret = 1 ;

                        return ret ;

                        // 위의 코드를 간단히 만드는 방법.
                        // return (item1.getNo() - item2.getNo()) ;
                    }
                } ;

                Collections.sort(itemList, noAsc) ;
                adapter.notifyDataSetChanged() ;
            }
        });

다음은 "No DESC" Button 클릭 시, "No" 항목에 대해 내림차순으로 정렬되도록 작성한 코드입니다. 높은 숫자(5)부터 낮은 숫자(1) 순으로 화면에 표시됩니다.

[STEP-7.2] "MainActivity.java" - "No DESC" 클릭 시, "No" 항목에 대한 내림차순 정렬.
        Button buttonNoDesc = (Button) findViewById(R.id.buttonNoDesc) ;
        buttonNoDesc.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                Comparator<ListViewItem> noDesc = new Comparator<ListViewItem>() {
                    @Override
                    public int compare(ListViewItem item1, ListViewItem item2) {
                        int ret = 0 ;

                        if (item1.getNo() < item2.getNo())
                            ret = 1 ;
                        else if (item1.getNo() == item2.getNo())
                            ret = 0 ;
                        else
                            ret = -1 ;

                        return ret ;

                        // 위의 코드를 간단히 만드는 방법.
                        // return (item2.getNo() - item1.getNo()) ;
                    }
                } ;

                Collections.sort(itemList, noDesc) ;
                adapter.notifyDataSetChanged() ;
            }
        });

이번엔 문자열 기준으로 정렬하는 코드를 살펴 보도록 하겠습니다. "Text ASC" Button 클릭 시, 알파벳 순으로 오름차순 정렬을 하도록 작성한 코드입니다. 순서 상 앞에 위치하는 알파벳('B')부터 뒤에 위치하는 알파벳('Q') 순으로 화면에 정렬됩니다.

[STEP-7.3] "MainActivity.java" - "Text ASC" 클릭 시, "Text" 항목에 대한 오름차순 정렬.

Button buttonTextAsc = (Button) findViewById(R.id.buttonTextAsc) ; buttonTextAsc.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { Comparator<ListViewItem> textAsc = new Comparator<ListViewItem>() { @Override public int compare(ListViewItem item1, ListViewItem item2) { return item1.getText().compareTo(item2.getText()) ; // 아래와 같은 코드 /* int ret ; if (item1.getText().compareTo(item2.getText()) < 0) // item1이 작은 경우, ret = -1 ; else if (item1.getText().compareTo(item2.getText()) == 0) ret = 0 ; else // item1이 큰 경우, ret = 1 ; return ret ; */ } } ; Collections.sort(itemList, textAsc) ; adapter.notifyDataSetChanged() ; } });

아래는 "Text DESC" Button 클릭 시, "Text" 항목에 대해 내림차순으로 정렬한 코드입니다.

[STEP-7.4] "MainActivity.java" - "Text DESC" 클릭 시, "Text" 항목에 대한 내림차순 정렬.
        Button buttonTextDesc = (Button) findViewById(R.id.buttonTextDesc) ;
        buttonTextDesc.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                Comparator<ListViewItem> textDesc = new Comparator<ListViewItem>() {
                    @Override
                    public int compare(ListViewItem item1, ListViewItem item2) {
                        return item2.getText().compareTo(item1.getText()) ;
                        // 아래와 같은 코드
                        /*
                        int ret ;

                        if (item1.getText().compareTo(item2.getText()) < 0)      // item1이 작은 경우,
                            ret = 1 ;
                        else if (item1.getText().compareTo(item2.getText()) == 0)
                            ret = 0 ;
                        else                                        // item1이 큰 경우,
                            ret = -1 ;

                        return ret ;
                        */
                    }
                } ;

                Collections.sort(itemList, textDesc) ;
                adapter.notifyDataSetChanged() ;
            }
        });

3. 예제 실행 화면.

예제를 작성하고 실행하면, 다음과 같은 실행 화면이 출력됩니다.

리스트뷰 정렬 예제 실행 화면


"No ASC"와 "No DESC" 버튼을 눌렀을 때, 각각 "No"에 대한 오름차순 및 내림차순으로 정렬된 결과는 아래와 같습니다.

리스트뷰 정수 타입 정렬


다음은 "Text ASC", "Text DESC" 버튼을 눌렀을 때, "Text" 값에 대한 오름차순, 내림차순 정렬 결과입니다.

리스트뷰 문자열 타입 정렬


4. 두 가지 이상의 항목을 기준으로 아이템 정렬하기.

위에서 살펴본 예제에서는 ListView 아이템에서 "No"와 "Text" 중 한 가지 항목에 대해서만 정렬하는 코드를 작성하였습니다. 그런데 만약 "No" 항목에서 중복된 값이 존재한다면 어떻게 해야 할까요?

리스트뷰 항목의 중복


물론 예제처럼, compare()함수에서 0을 리턴함으로써 아이템 위치의 "재배치"를 수행하지 않는 방법을 선택할 수도 있습니다. 하지만 어떤 상황에서는, "No" 항목이 같으면 그 다음 "Text" 항목을 비교해서라도 아이템을 정렬해야만 하는 경우도 있죠.


이런 경우, compare() 함수에서 두 가지 항목에 대한 비교를 수행하여 아이템의 순서를 결정해주면 됩니다.

    "No"와 "Text" 두 가지 항목 비교
    Comparator<ListViewItem> noAscTextAsc = new Comparator<ListViewItem>() {
        @Override
        public int compare(ListViewItem item1, ListViewItem item2) {
            int ret ;

            if (item1.getNo() < item2.getNo()) {
                ret = -1;
            } else if (item1.getNo() == item2.getNo()) {
                ret = item1.getText().compareTo(item2.getText()) ;
            } else {
                ret = 1;
            }

            return ret ;
        }
    } ;

    Collections.sort(itemList, noAscTextAsc) ;
    adapter.notifyDataSetChanged() ;

리스트뷰 두 가지 항목 비교 결과


5. 참고.


ANDROID 프로그래밍/LISTVIEW , , , , , , , ,

  1. Blog Icon

    정말로 잘 봤습니다. 늘 고마운 마음 전합니다.

  2. 오히려 제가 드릴 말씀이네요.
    감사합니다.

  3. Blog Icon
    Mayihelpyou

    혀를 내두를 정도에 깔끔한 정리와 체계적인 탤런트를 가지고 계시네요 감탄하고갑니다.
    언젠간 명서의 저자로 만날것같네요

    항상 감사드립니다.

  4. 과분한 칭찬에 몸둘바를 모르겠네요. ^^;
    계속해서 알찬 내용들 담을 수 있도록 노력하겠습니다.
    감사합니다.

  5. Blog Icon
    Mayihelpyou

    괜한 질문에 번거로울지 모르겠습니다만... 절박하여 이렇게 여쭙고 싶은데요,

    댓글로 여쭙기엔 소통이 쉽지않을것같아 지식인에 올린 뒤 링크하나 남깁니다. http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040104&docId=262273953

    시간나신다면 도와주시면 감사하겠습니다.

  6. 지식인에 올리신 글은 읽어봤는데요.
    앱 설계에 관한 질문글이네요.
    음.. 어떻게 답변을 해 드려야 할지.. 참 난감하네요.
    방법은 많고, 정답이 정해진 것도 아니니...

    음.. 제가 드릴 수 있는 답변은...
    일단 생각나는대로 만들어보시는 게 좋다...입니다.
    너무 완벽한 방법을 갖추어서 하려고 하지 마시고..
    주어진 문제를 하나씩 해결해가면서 앱을 만들어보세요.
    앱을 만들다가 이 방법이 아니다 싶으시면 그 때 방법을 바꿔도 괜찮으니..

    한번의 고민을 10일 하는 것보다.. 하루에 앱 하나씩 열번 만드는 시행착오를 거치는 게 더 좋을 수 있습니다.

    좀 더 구체적인 답변을 드릴 수 있으면 좋겠는데..
    음.. 참.. 뭔가 가이드 해드리기 쉽지 않네요.
    도움이 되어 드리지 못해 죄송합니다.

  7. Blog Icon
    익명

    비밀댓글입니다

  8. 먼저 첫 번째 질문에 대한 답은, 작업하신 "임의로 꺼지도록 만드는 방법"을 적용하는 게 맞습니다.
    리스트뷰 내의 아이템뷰의 데이터가 갱신되면 이전 아이템뷰의 상태가 자동으로 갱신(또는 초기화)될 것 같지만, 안드로이드에서는 아마 그 결정을 개발자가 하도록 만들어둔 것 같아요.
    그래서 화면에 표시된 아이템뷰에 데이터가 갱신될 때, 아이템 내의 자식 뷰들의 상태를 직접 제어해줘야 합니다.
    Choice(singleChoice, multiChoice) 기능이 적용된 리스트뷰의 아이템을 제어할 때도 clearChoices() 함수를 직접 호출해주는 이유가 바로 그런 것 때문이죠.

    두 번째 질문에 대해 답을 드리자면.. 코드를 잘못 작성하셨네요.
    결과적으로, 리스트는 제대로 전달되었으나, targetArray.remove(j)를 호출함으로써 리스트의 인덱스가 틀어진 것입니다.

    보통, 리스트를 가지고 작업을 할 때 리스트에 데이터를 추가하거나, 수정할 때는 큰 주의가 필요하지 않지만,
    리스트에서 루프를 돌며 데이터를 삭제하는 경우에는 주의가 필요합니다.
    왜냐하면 삭제하는 코드 자체가 리스트 크기 및 인덱스에 영향을 주기 때문입니다.
    그래서 보통 리스트를 삭제할 때는 뒤에서부터(ArrayList.size()-1) 앞으로 진행 하죠.
    관련 내용은 (http://recipes4dev.tistory.com/59, "안드로이드 리스트뷰 다중 선택 처리하기")의 ["2.4 "Delete" Button 클릭 시 선택 아이템 삭제"]에 설명되어 있으니 참조하시기 바랍니다.

    올려주신 코드를 제가 직접 수정해서 알려드리는 건 도움이 더 안될테니, "http://recipes4dev.tistory.com/59"의 내용을 확인하시고 수정해보시기 바랍니다.

    또 다른 질문 있으시면 다시 질문글 올려주세요.

    감사합니다.

  9. Blog Icon
    임민규

    항상 리스트가 정렬되었으면 하는데 정렬코드를 getView 함수에다가 넣어야하나요? 아니면 다른곳에다가 넣어야하나요?

  10. getView 메서드에는 리스트 정렬 코드를 작성하지 마시고, 다른 곳에 작성하셔야 합니다.

    항상 리스트가 정렬되어 있기를 원하신다면, 리스트에 아이템을 추가할 때 리스트를 정렬해 주시면 될 것 같습니다.

    감사합니다.

  11. Blog Icon
    구독

    버튼 하나로 오름차순 내림차순 정렬은 어떻게 해야나요??

  12. 1. 현재 오름차순인지 내림차순인지 상태를 따로 저장하고 있다가,
    2. 버튼이 눌려지면 현재 상태에 따라 정렬을 수행한 다음
    3. 상태를 전환하여 저장하면 될 것 같습니다.

    감사합니다.

  13. 안녕하세요. 검색이 가능한 커스텀 ListView를 구현한 후
    Spinner를 이용해 특정 문자가 포함된 item만 따로따로 리스트뷰에 집어넣고 싶은데
    어떻게 해야 하나요?

  14. 질문글에 올려주신 내용만으로는 정확한 요구사항을 식별하기가 힘드네요.

    조금 더 자세한 내용이 있으면 구체적인 형태를 잡기에 더 좋을 것 같고요.

    먼저, 일단 어떤 형태로든 만들어보시는 걸 추천드립니다.

    Spinner 넣고, 특정 문자 검색하고, 아이템 데이터 빼오고... 뭐 이런 것들 만들어보시면서 막히는 부분 있으시면 다시 질문글 남겨주시면, 조금 더 수월하게 도움드릴 수 있을 것 같습니다.

    감사합니다.

  15. 안녕하세요. 답변 정말정말 감사합니다.
    덕분에 정말 큰 도움을 받았습니다. ㅠㅠ 어떻게 감사를 드려야 할지 모르겠어요.
    다름이 아니오라, 제가 부족한 점이 많다보니 제 생각대로 일련의 코딩을 해보다가 턱 막히더라고요 ㅠㅠ

    1.Spinner를 넣기

    public class MainActivity extends AppCompatActivity {
    ListViewItem item = new ListViewItem();
    ArrayList<ListViewItem> itemList = new ArrayList<ListViewItem>();
    //코딩 계속

    Spinner spinner;

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

    //중간에 listview의 어댑터 설정 및 연결과정이 있었습니다.

    //xml에 Id가 Spinner_menu인 Spinner를 가져왔습니다.
    Spinner s = (Spinner)findViewById(R.id.spinner_menu);

    //그다음 스피너를 선택했을 때
    s.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

    //2. 아이템의 이름 중 도서가 포함되어 있을 경우(특정 문자 검색)
    if(item.getTitle().contains("도서"))
    {
    //itemList에 item을 넣는다..?
    itemList.add(item);

    }

    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }
    });

    여기까지 오긴 했는데 충돌이 난 건지 빌드를 해도 앱이 실행이 되질 않더라고요 ㅠㅠ 조언 부탁드립니다.

  16. 일단, 실행 에러가 발생할 때는 정확한 에러 메시지를 확인하시는 게 우선입니다.
    안드로이드 스튜디오 로그캣에 출력되는 메시지를 살펴보셔서, 앱이 멈출 때 어떤 에러가 출력되는지 잘 확인해 보세요.

    에러 메시지를 살펴보면 대략적인 원인을 유추하거나, 구글링을 통해 문제점을 확인할 수 있습니다.

    그리고 올려주신 코드를 보면요.
    리스트뷰를 사용하는 방법에 대해 조금 더 숙지하실 필요가 있을 것 같습니다.

    어떻게 동작하는 앱을 만드시려고 하는지 정확히 모르겠지만,
    스피너 선택 시 itemList.add()에서 사용하는 item은 Activity가 만들어질 때 new로 생성된 ListViewItem의 인스턴스이거든요.

    상식적으로 생각해봐도, 어떤 의도를 가지고 코드를 작성하신건지 잘 이해가 되지 않습니다.

    만들고자 하는 기능의 요구사항과 절차를 조금 더 고민해보시고, 리스트뷰의 기본 사용법과 동작에 대해 조금 더 공부해보시는 것을 추천드립니다.

    감사합니다.

  17. 답변 감사합니다.

  18. 앞서 남겨드린 답변이 도움되셨으면 좋겠습니다.
    감사합니다.

  19. Blog Icon
    개발자

    진짜 대단하십니다 크으..... 깔끔한 설명덕분에 정렬 기능도 잘 배워갑니다 ㅠ

  20. 도움이 되신 것 같아서 다행이네요.
    칭찬 댓글 남겨 주셔셔 감사합니다.