안드로이드 리스트뷰 기본 사용법. (Android ListView)

2016. 1. 6. 15:43


1. 안드로이드 ListView

ListView는 사용자가 정의한 데이터 목록을 아이템 단위로 구성하여 화면에 출력하는 ViewGroup의 한 종류입니다. ListView의 아이템들은 세로 방향으로 나열되며, 아이템의 개수가 많아짐에 따라 ListView에 표시될 내용이 ListView의 크기(width,height)를 넘어서게 되면 스크롤 기능을 사용해 ListView의 표시 기준 위치를 이동시킬 수 있습니다.


ListView에 표시되는 아이템은 단순히 Text만 출력하는 구조가 될 수 있고, Image, Button, CheckBox 등 여러 View의 조합으로 구성되는 좀 더 복잡한 형태(Custom)가 될 수도 있습니다.


ListView는 UI(User Interface)를 구성함에 있어 가장 많이 사용되는 컴포넌트 중 하나이며 안드로이드 시스템의 연락처, 환경설정 등이 ListView의 대표적인 예입니다.

대표적인 리스트뷰 예제

!참고 : 안드로이드 ViewViewGroup

안드로이드에서 UI 화면은 View와 ViewGroup을 사용하여 구성됩니다.
View는 사용자에게 어떤 내용을 보여주거나 입력을 받아들이기 위해 화면에 그려지는 기본 객체를 말합니다. TextView, Button, CheckBox 등이 대표적이죠.


반면에 ViewGroup은 이름 그대로 View들이 모인 Group을 말합니다. 즉, 화면에 표시할 하나 이상의 View를 포함하는 컨테이너 역할을 수행하는 것이죠. Layout, ListView 등이 ViewGroup에 속하며 View뿐만 아니라 ViewGroup 또한 포함할 수 있습니다.


ListView는 ViewGroup에 속합니다. 즉, 데이터를 화면에 표시하기 위해서는 View(또는 ViewGroup) 객체가 ListView에 추가되어야 하며, 하나의 View(또는 ViewGroup)는 하나의 아이템 정보를 표시하게 됩니다.

리스트뷰 계층구조

1.1 Adapter

ListView에 데이터를 추가하여 화면에 표시하기 위해서는 Adapter를 사용해야 합니다. 일반적으로 "어댑터"라는 의미는 "장치 또는 기계의 다른 부분을 연결하는 장치로, 적합하지 않은 두 개의 부분을 전기적 또는 기계적으로 접속하기 위한 장치 또는 도구"를 말합니다. ListView에서 사용하는 Adapter 또한 의미적으로 크게 다르지 않습니다. 유사한 문장으로 표현하자면 "사용자가 정의한 데이터를 ListView에 출력하기 위해 사용하는 객체로, 사용자 데이터와 화면 출력 View로 이루어진 두 개의 부분을 이어주는 객체" 정도가 되겠네요. 즉, Adapter가 하는 역할은 사용자 데이터를 입력받아 View를 생성하는 것이며 Adapter에서 생성되는 View는 ListView 내 하나의 아이템 영역에 표시되는 것입니다.

어댑터 역할


2. ListView 기본 사용법.

안드로이드에서 기본적으로 제공하는 ListView는 문자열을 출력하기 위해 사용하는 TextView만을 포함하는 단순한 구조를 가지고 있습니다. 물론 문자열 목록을 출력하는 기본적인 ListView만으로도 충분히 유용한 기능을 가진 앱을 만들 수 있지만 좀 더 편리하고 아름다운 UI 제공을 위해 기본 ListView를 확장하여 일반적인 UI 화면에 사용하는 컴포넌트들을 그대로 사용하여 구성할 수 있습니다. 즉, TextView, ImageView, Button 등을 마음대로 배치하여 ListView의 내용을 구성할 수 있다는 뜻이죠. 


하지만 다양한 컴포넌트들로 구성된 ListView를 만들기 위해서는 조금 번거로운(?) 작업을 해줘야 합니다.

ListView 아이템에 대한 Layout을 구성해야 하고, Layout에 출력될 데이터에 대한 새로운 클래스를 정의해야 하며, 사용자 데이터를 Layout에 정의된 형태의 View로 변환하기 위한 Adapter 클래스도 상속받아 필요한 함수를 채워줘야 합니다. 

이렇게 기본 ListView로부터 확장된 기능을 가지는 ListView를 Custom ListView라고 말하는데, 이에 대한 설명은 추후 자세히 정리하도록 하겠습니다. 여기서는 ListView 사용법에 대한 이해를 위해 우선, 기본 ListView에 대한 작업 절차를 진행하도록 하겠습니다.

2.1 워크플로우

리스트뷰 만들기 절차


2.2 ListView가 표시될 위치 결정.

UI 화면을 구성할 때 가장 먼저 해야 할 일은 어떤 위젯을 사용할 것인지, 어디에 위치시킬 것인지 결정하는 것입니다. 보통 UI 화면을 구성할 때 여러 위젯들을 조합하는 경우가 대부분이어서 구성 작업에 많은 고민이 필요합니다. UI 화면 구성은 사용자의 사용 편의성과도 직결되는 내용이라 쉽게 결정하기 힘든 작업이죠. 이를 위해 보통 설계단계에서 프로토타이핑 도구 등을 사용하여 미리 화면에 대한 구성 설계를 진행하기도 합니다. 


음, 더 자세한 내용은 여기서 다룰 내용이 아니기에, 지금은 가장 기본적인 형태의 ListView 사용법에 대한 단순 예제로만 UI 화면을 구성하겠습니다.


간단하게 MainActivity에 ListView를 생성합니다. MainActivity에 대한 Layout Resource는 "activity_main.xml" 파일(또는 "content_main.xml")에 작성합니다.

<?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.example.madwin.listviewexample1.MainActivity"
    tools:showIn="@layout/activity_main">

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

</RelativeLayout>

2.3 ListView 아이템에 표시될 사용자 데이터 정의.

이제 ListView가 표시될 위치를 결정하였으니 ListView에 어떤 내용을 보여줄 것인지 정의해야 합니다. ListView에 문자열만 표시할 것이므로 string 타입의 배열을 선언합니다.

public class MainActivity extends AppCompatActivity {
    static final String[] LIST_MENU = {"LIST1", "LIST2", "LIST3"} ;
    // ... 코드 계속
}
class MainActivity : AppCompatActivity() {
    val LIST_MENU = arrayOf("LIST1", "LIST2", "LIST3")
    // ... 코드 계속
}

2.4 Adapter 생성 후 ListView에 지정.

사용자 데이터가 준비되었으니 해당 데이터를 입력받아 View로 만들어줄 Adapter를 생성해야겠죠. 안드로이드 SDK에서 기본적으로 제공하는 Adapter는 여러 종류가 있고 사용자가 용도에 맞게 선택해서 사용할 수 있는데, 여기서는 string 배열을 입력으로 받으므로 ArrayAdapter를 사용하겠습니다.

[단계-5.2] onCreate()에서 1초 마다 시각을 갱신하는 코드 작성. 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState) ;
        setContentView(R.layout.activity_main) ;

        ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, LIST_MENU) ;

        ListView listview = (ListView) findViewById(R.id.listview1) ;
        listview.setAdapter(adapter) ;
        // ... 코드 계속.
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        // ...

        val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, LIST_MENU)

        val listview = findViewById(R.id.listview1) as ListView
        listview.setAdapter(adapter)

        // ... 코드 계속.
    }

!코드 설명

위의 코드에서 사용한 ArrayAdapter의 생성자는 3개의 파라미터를 가집니다.

 ArrayAdapter(Context context, int resource, T[] objects)
  • context : 안드로이드 시스템에서 제공되는 어플리케이션 전역 환경 정보에 대한 인터페이스. (Activity를 통해 사용 가능)
  • resource : View로 매핑될 Resource Id. "android.R.layout.simple_list_item_1"은 TextView 위젯으로 구성된 ListView 아이템 리소스 Id.
  • objects : 배열로 선언된 사용자 데이터.

여기까지 작업이 완료되면 TextView 위젯들로 구성된 기본적인 ListView가 화면에 표시됩니다.

2.5 ListView 클릭 이벤트 처리

보통 ListView는 단순히 데이터를 리스트(목록) 형태로 보여주기 위해 사용하기도 하지만, 리스트 아이템 자체를 선택 가능(클릭)하도록 만들어 메뉴처럼 사용할 수도 있습니다. ListView가 사용자의 아이템 터치 입력을 받을 수 있도록 만드려면 ListView에 Click 이벤트에 대한 리스너를 설정해주면 됩니다.

    listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        // 코드 계속 ...

        @Override
        public void onItemClick(AdapterView parent, View v, int position, long id) {

            // get TextView's Text.
            String strText = (String) parent.getItemAtPosition(position) ;

            // TODO : use strText
        }
    }) ;
    override fun onCreate(savedInstanceState: Bundle?) {
        // 코드 계속 ...

        listview.onItemClickListener = object : AdapterView.OnItemClickListener {
            override fun onItemClick(parent: AdapterView<*>, v: View, position: Int, id: Long) {

                // get TextView's Text.
                val strText = parent.getItemAtPosition(position) as String

                // TODO : use strText
            }
        }
    }

onItemClick() 함수에서 ListView 아이템인 TextView의 텍스트를 가져오려면 위의 주석에 있는 내용처럼 parent.getItemAtPosition() 함수를 사용하면 됩니다.

3. Fragment에서 ListView 사용하기

지금까지의 ListView 기본 사용법은 Activity에 ListView를 추가할 때 사용하는 방법입니다. 만약 동일한 코드를 사용하여 Fragment에 ListView를 추가하면 어떤 결과가 나올까요? 직접 코드를 작성하여 빌드해보면 아시겠지만 "에러가 발생"합니다.

    error: no suitable constructor found for ArrayAdapter(MainActivityFragment,int,String[])
        ...
    error: cannot find symbol method findViewById(int)

첫 번째 에러가 발생하는 원인은 ArrayAdapter 생성자의 첫번째 파라미터로 전달되는 Context에 대한 접근 문제 때문입니다. Activity는 android.content.Context로부터 상속받은 클래스이므로 Context의 기능을 그대로 이용할 수 있기 때문에 onCreate() 함수에서 ArrayAdapter 생성자의 첫번째 파라미터로 this를 전달할 수 있습니다. 하지만 Fragment는 java.lang.Object로부터 직접 상속받은 클래스입니다. 즉, Context와는 전혀 관계가 없는 상태라서 this를 사용할 수 없는거죠. 

그럼 Fragment에서는 ListView를 사용할 수 없는 걸까요? 아닙니다. 당연히 해결할 수 있는 방법이 존재합니다. 그것도 아주 간단하게 말이죠. 바로 Fragment에서 자신이 속한 Activity의 참조를 얻어온 다음 ArrayAdapter의 생성자로 전달하는 것입니다. 이미 Fragment에는 Activity의 참조를 획득할 수 있는 getActivity()라는 함수가 있습니다.


두 번째 에러는 findViewById() 함수 호출 때문입니다. findViewById() 함수는 Fragment의 멤버 함수가 아닙니다. View의 멤버 함수이죠. 즉, Fragment의 멤버 함수가 아닌 findViewById() 함수를 Fragment에서 호출하려고 하니 에러가 발생하는 것입니다.

해결 방법은 LayoutInflater를 사용하여 Resource Layout을 View로 변환한 다음 해당 View를 사용하여 findViewById()를 호출하는 것입니다.


Fragment에 ListView를 추가하는 코드는 다음처럼 작성하시면 됩니다.

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment1, null) ;

        ArrayAdapter Adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, LIST_MENU) ;

        ListView listview = (ListView) view.findViewById(R.id.listview1) ;
        listview.setAdapter(adapter) ;

        return view ;
    }
    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment1, null) ;

        val adapter = ArrayAdapter((getActivity(), android.R.layout.simple_list_item_1, LIST_MENU)

        val listview = view.findViewById(R.id.listview1) as ListView
        listview.setAdapter(adapter)

        return view
    }

4. ListView 기본 사용법 예제 실행 화면

위의 예제 소스를 순서대로 작성한 뒤 실행하면 다음과 같은 화면이 출력됩니다.
안드로이드 기본 생성 코드에 Material Design이 적용되었는지 여부에 따라 화면이 조금 다르게 나올 수 있으며 기기는 넥서스7 2세대를 사용하였습니다.

리스트뷰 예제 실행화면

.END.


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

  1. 이전 댓글 더보기
  2. Blog Icon
    김좆밥

    정리를 정말 잘하셨네요. 최고의 선생입니다.

    어댑터가 뭔지 십수번 봐도 잘 모르겠는데 빡대가리의 벽을 좀 깨주신거 같아요.

    감사합니다.

  3. 제가 정리를 잘 했다기보다는, 그 동안 공부해오신 내공이 축적되어 그 힘이 발휘되는 것이겠지요.

    뽀따는 거들 뿐...

    감사합니다.

  4. Blog Icon
    호구선생

    리스트뷰 내용 잘 공부했습니다.

  5. 도움이 되셨길 바랍니다.

    감사합니다.

  6. Blog Icon
    초보

    2.3 ListView 아이템에 표시될 사용자 데이터 정의 이거를 어디에 선언해야되는지요..? 2.2처럼 activity_main.xml 파일에다가선언해야되나요? 또 2.4는 Adapter를어떻게생성하고 Listview지정하나요?

  7. 사용자 데이터를 어디에, 어떤 형태로 정의할 것인지는, 순전히 개발자의 선택입니다.

    본문의 예제처럼 리스트뷰가 포함된 액티비티에 선언해도 되고, 다른 액티비티에 선언해도 됩니다. 아니면 싱글톤으로 정의해도 되고, 파일이나 DB에 직접 바로 관리해도 됩니다.

    사용자 데이터를 어떻게 처리할 것인지, 어느 정도 범위에서 접근할 수 있도록 만들 것인지.. 등등에 따라 직접 결정하시면 되는 것이죠.

    제가 남겨드린 답변이 이해가 잘 안되시다면, 일단 본문의 예제처럼 따라해보세요. 그리고 기능 구현에 따라 점점 확장해가며 문제를 수정해가다보면, 해결 방법을 찾을 수 있을 거라 생각합니다.

    감사합니다.

  8. Blog Icon
    안스초보

    listview 내 아이탬의 텍스트를 사용자가 원하는대로 수정하려면 edittext를 이용해야하는건가요???

  9. 일단 답변부터 드리자면, 리스트뷰 아이템 텍스트를 수정하기 위해 반드시 에디트텍스트를 사용할 필요는 없습니다.

    요구사항에 맞게 만들면됩니다.

    버튼을 눌렀을 때 아이템 텍스트가 바뀌게만들 수도 있고, 인터넷에서 가져온 데이터를 이용해서 텍스트를 표시할 수도 있습니다.

    아이템 텍스트를 변경하기 위해 에디트텍스트를 사용해야 하는 규칙같은 건 없는것이죠.

    물론, 리스트뷰 아이템을 선택하고 직접 내용을 수정할 때, 에디트텍스트가 가장 많이 사용되긴 하지만, "반드시" 에디트텍스트를 사용해야 하는 것은 아니라는 것이죠.

    충분한 답변이 되었는지 모르겠네요.

    추가적으로 궁금한 점이 있으면, 또 질문글 남겨주세요.

    감사합니다.

  10. Blog Icon

    안녕하세요 지금 안드로이드 스튜디오를 공부 하고있습니다.
    .setAdapter(adapter); 이부분만 넣으면 버튼 클릭시 어플이 강제 종료되는데 데이터랑 관련이 있나요?
    스튜디오 내에서 에러는 안뜹니다.

  11. 답변이 좀 늦었네요. 죄송합니다.
    질문하신 내용의 문제는, 아마 리스트뷰에 대한 참조가 잘못되어서(null) 발생한 문제같습니다.

    정확한 원인을 알기 위해서는, 앱이 종료될 때 출력되는 에러 메시지 또는 작성하신 코드에 대한 확인이 필요할 것 같네요.

    아직 문제를 해결하지 못하셨다면, 에러 메시지 또는 코드를 댓글로 남겨주세요.

    감사합니다.

  12. Blog Icon

    안녕하세요. 리스트뷰 밑에 리스트뷰를 넣었는데 위에 있는 리스트뷰는 잘나오는데 밑에는 안나옵니다.
    오류나 강제종료는 안뜹니다.
    리사이클뷰를 사용하라는데 그렇게 되면 다시 만들어야해서 어댑터를 미리 세팅하지 말라는데 다른방법이 있나요?

  13. 리스트뷰 밑에 리스트뷰를 넣는다고 하나가 잘 나오지 않을 이유는 없습니다.
    아마 두 개의 리스트뷰를 사용하면서 코드가 꼬이지 않았을까... 감히 추측해 봅니다.

    조금 더 찬찬히 살펴보시면 문제 원인을 찾으실 수 있을 것 같은데요, 혹시라도 원인이 잘 드러나지 않는다면, 관련 코드를 질문글에 올려주세요.
    그러면 도움 드리기 더 수월할 것 같습니다.

    감사합니다.

  14. Blog Icon

    안녕하세요. 위에 댓글 작성한 사람인데요.
    질문글을 어디에다 올리는지 몰라서 상단에 있는 이메일로 코드를 보냈습니다.
    확인 부탁드립니다.

  15. 음, 일단 보내신 메일은 봤는데, 전체적인 소스를 확인하기에는 무리가 있고, 리스트뷰 관련 부분만 확인해봤습니다. 코드 상으로는 특별히 문제가 없어 보이는데요.

    먼저 리스트뷰가 화면에 표시는 되나요? 미리 onCreate()에서 데이터를 임의로 넣어서 화면에 나오는지 확인이 필요할 것 같습니다.

    그것부터 확인해 보시고 다시 질문글 남겨주세요.

    그리고 메일로 소스를 보내주셔도, 여건 상 소스를 확인하기 힘듭니다.

    질문글 남겨주실 때처럼, 댓글 창에 핵심이 되는 코드만 올려주시면 될 것 같습니다.

    감사합니다.

  16. Blog Icon

    디자인 탭에서 보면 리스트뷰가 스피너 밑에 잘나옵니다. 혹시 몰라 리스트뷰 밑에 말고 새로 만들어서
    코드를 복붙했는데 나오지 않네요. 임의 데이터는 잘 나옵니다.

  17. 답변이 많이 늦었습니다. ㅜㅜ

    근래 개인적인 일로 너무 정신이 없어서 블로그를 관리할 여유가 없네요.
    죄송합니다.

    문제를 해결하셨는지는 모르겠지만, 일단 답변을 드리자면...

    임의 데이터가 제대로 나온다면, 리스트뷰 화면 표시는 문제가 없다고 봐도 될 것 같습니다.
    그렇다면 데이터를 넣는 부분을 확인해봐야 할 것 같네요.

    일단 급한대로 AsyncTask의 onPostExecute() 메서드에서 디버그 메시지를 출력하여 데이터가 잘 들어가는지 확인해보시기 바랍니다.

    일단, 화면에 표시되는 과정에서 하나 하나 확인해볼 수 밖에 없을 것 같네요.

    감사합니다.

  18. Blog Icon
    쪼꼬미

    안녕하세요 뽀따님!!!!!
    오늘도 와서 또 배우고 갑니다 이거로 리스트뷰 화면을 잘 만들었어요 너무 감사합니다
    추운데 감기조심하셔용

  19. 도움이 되어서 다행이네요.
    쪼꼬미님도 추운 겨울, 감기 조심하세요.

    감사합니다.

  20. Blog Icon
    Unknown

    물론 다들 훌륭하시지만 설명이 독창적이신 것 같습니다!
    초보들이 궁금해하는 '왜 이게 들어갔지?'에 대한 답이 정확히 나와있어서
    정말 많은 도움을 받고 갑니다!
    그나저나 구글의 거의 대다수 키워드를 차지하고 계시더라구요 ㅋㅋㅋㅋㅋ
    팬입니다

  21. 제가 작성한 내용의 스타일이, 구글이 맘에 들어하는 방식인가봐요. 검색 상위에 올라있는 걸 보면... 흐흐.. 감사할 따름이죠.

    허접한 블로그 내용에, 칭찬과 격려의 댓글을 남겨주셔서 정말 감사합니다.

  22. Blog Icon
    초보

    처음으로 DB에서 data 불러와서 리스트 뷰에다가 표현하는 거 하고 있는데, 도움 많이 받고 갑니다~!

  23. 도움이 되셨다니 다행이네요.

    방문해 주셔서 감사합니다.

  24. Blog Icon
    ㅎㅎㅎ

    2017년에 졸작하면서 참고했던 글인데 아직도 정성스럽게 답변을 달아주시네요 너무 대단하십니다 ^^ 2020년엔 꼭 좋은일만 생기시고 건강하시길 바랍니다 감사합니다 -20대 초보개발자가-

  25. 답글에 정성만 가득할 뿐... 실질적인 도움을 드리고 있는지는 모르겠네요.... ㅜㅜ

    20대 초보개발자님도 2020년 멋진 한해 보내시길 바랍니다.

    감사합니다.

  26. Blog Icon
    코틀린개발

    이렇게 에러가 나는데 어떻게 해결해야 할 까요??

    E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.spacetalk.test01, PID: 15213
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.spacetalk.test01/com.spacetalk.test01.MainActivity}: java.lang.IllegalStateException: listview1 must not be null
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2440)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2500)
    at android.app.ActivityThread.access$900(ActivityThread.java:163)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1362)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5585)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
    Caused by: java.lang.IllegalStateException: listview1 must not be null
    at com.spacetalk.test01.ListFragment.onCreateView(ListFragment.kt:40)
    at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
    at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
    at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
    at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
    at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
    at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
    at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
    at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663)
    at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
    at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
    at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
    at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1238)
    at android.app.Activity.performStart(Activity.java:6295)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403)



    override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
    ): View? {
    val view: View = inflater.inflate(R.layout.fragment_list, null)


    val adapter = ArrayAdapter<String>(view.context, android.R.layout.simple_list_item_1, LIST_MENU)

    listview1.adapter = adapter <- 에러나는 부분

    return view
    }

  27. listview1 이 null 이라고 나오는데요.
    listview1에 대한 참조를 획득하는 부분이 문제없이 작성되었는지, listview1이 null 값이 아닌지 확인해보시기 바랍니다.

    해결 방법을 아직 못 찾으셨다면, 다시 질문글 남겨주세요.

    감사합니다.

  28. Blog Icon
    아틀리에

    안녕하세요 앱에 관한 책을 살려고 했는데 이렇게 좋은 블로그를 찾아서 따라 하면서 공부를 하고있는 학생입니다 다름이 아니라 지금 자바 기초를 공부했고 앱을 만들어보고 싶어 이 블로그를 보면서 공부를 하고있는데 이 방법이 맞는건지 확신이 들지않아서 여쭤봅니다 앱을 처음 공부하는 사람이라면 하나씩 따라하면서 공부하는 것이 옳바른 방법인가요? 제가 따라하면 다음에 까먹고하여 질문드립니다.

  29. 흠.. 정답이 없는 질문이라.. 뭐라 답변을 드려야 할지 모르겠네요.

    개인마다 공부 방법이 다르고, 학습에 투자할 수 있는 시간도 다르고, 습득 능력도 다르기 때문에... 어떻게 하는 게 옳은지는 잘 모르겠어요.

    일단 확신이 드는 방법을 찾을 때 까지.. 그냥 계속 공부하시면 어떨까요? 방법은 조금씩 바꾸더라도, 계속 계속 하는거죠.

    만들고 실행하고 디버깅하고 또 만들고 실행하고 디버깅하고...

    그러다보면, 나만의 방법을 찾을 수 있지 않을까요?

    도움이 될만한 답을 드리지 못해 죄송합니다.

    감사합니다.

  30. Blog Icon
    도와주세요

    안녕하세요 좋은자료 감사합니다
    우선 listview를 이용하여 여러개 리스트를 출력하였습니다.
    문제는 스크롤인데 일반 터치해서 손가락 내리고 올리는 이벤트는 리스너로 구현을 해야 하는건지요?
    fastscroll은 원하는 기능은 아니고..문의드립니다.
    혹시 이것을 구현해 놓은것이 recycle listview인지요? 혹시 차이가 무엇인지 문의드립니다.

  31. 리스트뷰에 여러 개의 아이템을 추가했을 때, 스크롤이 안되던가요?
    리스트뷰 아이템이 리스트뷰 영역을 벗어날만큼 있을 때는 자동으로 스크롤 기능이 활성화됩니다.

    리사이클러뷰는 스크롤 기능 구현 유무와 관계없습니다.

    자세한 내용은 아래 링크에서 확인해보시기 바랍니다.

    "안드로이드 리스이클러뷰 기본 사용법"
    (https://recipes4dev.tistory.com/154)

    감사합니다.

  32. Blog Icon
    도와주세요

    안녕하세요
    Listview가 Fragment안에 들어있거든요
    이럴경우에 스크롤이 안먹나본데..해결방법이있나요?

  33. 음.. 딱히 스크롤이 안될 이유가 없을 것 같은데, 코드를 확인하지 못하니 이유를 알 수가 없네요.

    일단, 리스트뷰에 데이터가 많이(영역을 벗어날만큼) 들어가 있는지 먼저 확인해 보시고요.

    간단한 샘플 코드라도 올려주시면 원인을 확인하기가 더 쉬울 것 같습니다.

    감사합니다.

  34. Blog Icon
    안드슬레이브

    스크롤뷰 내에 Relativelayout 내에 리스트뷰를 구현하였습니다.
    그런데 여기서 문제가 두가지 확인이 되는데요

    1. 리스트 아이템이 하나밖에 나타나지 않음..소스 코드의 문제는 아닌걸로 파악됩니다.
    이유는 리스트뷰의 높이를 의도적으로 줬을시(ex 500dp)에는 아이템이 여러개가 잘 나오는 것이 확인이 되거든요..지금 값은 matchparent로 설정이 되어있는데..이유를 모르겠습니다. 아래 다른 여러 코드들이 있는데 그게 문제인가 싶어 리스트뷰 아래 코드를 다 삭제하고 해봐도 아이템이 하나밖에 나오질 않습니다..

    2.리스트뷰의 높이를 의도적으로 줬을시 아이템 리스트가 정상적으로 나온다고 했는데..
    이때 스크롤뷰의 스크롤 + 리스트뷰의 스크롤 두개가 중첩으로 일어나 따로따로 노는것을 확인했습니다.

    어떻게 해결하면 좋을까요? 감사합니다.

  35. 레이아웃 관련 코드가 조금 문제 있는 것으로 보여지는데요.

    질문글의 내용만으로는 정확한 원인을 파악하기가 쉽지 않네요.

    리스트뷰 높이를 의도적으로 줬을 때 아이템 여러개가 잘 나온다고 하셨으니, 리스트뷰 자체의 문제보다는 레이아웃 쪽 문제일 가능성이 큰 것 같습니다.

    일단 레이아웃 관련 코드를 먼저 검증해보시는 게 좋을 것 같네요.

    아니면 관련 코드를 질문글에 올려주시면 도움드리기 더 수월할 것 같습니다.

    감사합니다.

  36. Blog Icon
    안린이

    전설의 시작...
    좋은 글 많이 참조해서 앱 하나 만들어 보겠습니다. ㅎㅎ
    감사해요~!

  37. 정리된 내용은 많이 부족하지만,
    도움이 되셨으면 좋겠습니다.

    감사합니다.

  38. Blog Icon
    정보감사합니다

    정보 감사합니다
    다름이 아니라 activity와 intent를 이용해 리스트뷰에 문자열을 추가하는 프로그램을 만드는중인데
    옵션메뉴로 textstyle을 변경해보고싶은데 암만 찾아봐도 리스트뷰 안에있는 글씨를 textstyle 변경법이
    안나오더라고여
    혹시 아시나해서 질문 드려봅니다

  39. 답변이 많이 늦었네요.
    이미 해답을 찾지 못하셨다면 다시 질문글 남겨주세요.

    죄송합니다.

  40. Blog Icon
    코린이

    안녕하세요:) 저는 Fragment에서 GridView를 사용하려고 했으나 위에서 말씀하신 ListView에서의 어댑터 오류가 그대로 나타났습니다. 위에서는 ListView를 fragment에서 사용할 때 해결할 수 있는 방법을 알려주셨는데 혹시 GridView의 adapter는 어떻게 수정해야 할까요??

    public class Fragment_Home extends Fragment {
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    final GridView gv = (GridView) findViewById(R.id.gridView1);
    MyGridAdapter gAdapter = new MyGridAdapter(this);
    gv.setAdapter(gAdapter);

    return gv;
    }

    public class MyGridAdapter extends BaseAdapter {
    Context context;

    public MyGridAdapter(Context c) {
    context = c; // context 변수를 다른 메소드에서 사용하기 위함
    }

    @Override
    public int getCount() { // 그리드뷰에 보여질 이미지의 개수를 반환하도록 수정
    return posterID.length;
    }

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

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

    // 이미지 파일을 배열로 초기화
    Integer[] posterID = {R.drawable.bunsik, R.drawable.hansik, R.drawable.jungsik, R.drawable.ilsik, R.drawable.yangsik, R.drawable.cafe
    , R.drawable.chicken, R.drawable.pizza, R.drawable.jokbo, R.drawable.yasik};

    // 카테고리를 문자 배열로 초기화
    String[] posterTitle = {"분식","한식","중식","일식","양식","카페","치킨","피자","족발/보쌈","야식"};
    @Override
    public View getView(int position, View convertView, ViewGroup parent) { // 각 그리드뷰의 칸마다 이미지뷰를 생성해서 보여주게 함
    ImageView imageView = new ImageView(context);
    imageView.setLayoutParams(new GridView.LayoutParams(200, 300));
    imageView.setScaleType(ImageView.ScaleType.FIT_CENTER); // 그리드뷰 칸의 중앙에 배치
    imageView.setPadding(5,5,5,5);

    imageView.setImageResource(posterID[position]); // R.drawable.mov0x 이미지를 로드하여 출력
    //TODO 이미지를 클릭했을 때, 원래 이미지 크기가 보이도록 함
    final int pos = position;
    imageView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    Toast.makeText(getApplicationContext(),posterTitle[pos] + "click", Toast.LENGTH_LONG).show();
    }
    });
    return imageView;
    }
    }
    }

  41. 답글이 너무 늦어서 죄송합니다.
    건강 문제로 인해 블로그에 신경을 못 썼어요.
    질문글에 올려주신 문제는 해결하셨는지요?

    아직 문제를 해결하지 못하셨다면,
    에러 메시지와 같이 글 남겨주세요.

    도움드릴 수 있도록 노력하겠습니다.

    감사합니다.