마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

커스텀리스트뷰 갱신문제(코드설명)ㅠㅠ

0 추천
흠...아래질문했는데 답변자분처럼 했지만 전혀 안먹히네요..

그렇다고 오류가 나는것도 아니고...

아무리 adapter에 notifyDataSetChanged(); 해도 갱신이 안됩니다.

일단 코드좀 보여드릴께요 ㅎㅎ

        arrlist = new ArrayList<String>();
        arrlist2 = new ArrayList<String>();
        arrlist3 = new ArrayList<String>();
        arrlist4 = new ArrayList<String>();//요건 sqlite에서 받아온 데이터를 항목에따라 넣는것

        selectData();//sqlite 데이터 불러오기

        mListView = (ListView) findViewById(R.id.listreservealrm2);

        mAdapter = new ListViewAdapter(this);

        for (int i = 0; i < arrlist.size(); i++) { //sqlite에서 뽑아온 데이터수만큼 어뎁터에 추가

            mAdapter.addItem(getResources().getDrawable(R.drawable.movie_image),
                    arrlist.get(i), arrlist3.get(i), "알림취소", "감독 : "+arrlist4.get(i));

        }

        mListView.setAdapter(mAdapter);

요렇게 설정되어 있구요 .

요위에 화면은 onCreate 안에 있고, 화면실행화면 정상적으로 작동해서

데이터를 뿌려줍니다.

 

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                ListData4 mdata = mAdapter.mListData.get(position);
                String value = mdata.Rname;
                String sql = "delete from reserve_n where name ='" + value + "';";
                database.execSQL(sql);

                arrlist.clear();
                arrlist2.clear();
                arrlist3.clear();
                arrlist4.clear();

                ReserveAlrm2.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        selectData();
                        mAdapter.notifyDataSetChanged();
                    }
                });

            }
        });

// 리스트의 항목을 클릭했을때 sqlite에 해당데이터를 삭제 시킵니다.

그리고나서 arrlist를 순서대로 다 클리어 해줍니다.

그런후에 스레드를 이용해서 다시한번 selectdata를 해줍니다.

그런다음 어뎁터에 notifyDataSetChanged(); 를 해줍니다.

 

@Override
    protected void onDestroy(){
        super.onDestroy();
        database.close();
    }

    public void selectData(){
        String sql = "select * from reserve_n";
        Cursor result = database.rawQuery(sql,null);
        result.moveToFirst();
        while (!result.isAfterLast()){
            arrlist.add(result.getString(0));
            arrlist2.add(result.getString(1));
            arrlist3.add(result.getString(2));
            arrlist4.add(result.getString(3));
            result.moveToNext();
        }
        result.close();
    }

//요거는 데이터 뽑아오는 sqlite select 부분입니다.

사실이부분은 별로 상관이 없는듯 합니다

오류도 없고 다 정상적으로 작동되니깐요.

 

이게 어떻게 작동이 되냐면

arrlist가 클리어되는거는 제가 확인했습니다.

그런다음 다시 selectData() 로 인해 다시 sqlite 데이터를 불러오게 됩니다.

그런다음 리스트를 다시 갱신해줘야하는데

갱신이 전혀되질 않습니다.

물론 화면을 뒤로 나갔다가 들어오면 갱신이 되어 있습니다.ㅠㅠㅠ

삽질만 몇시간째인데 왜안되죠..;;ㅜㅜ

스레드에 안넣고도 해봣는데 안되네요;;ㅠㅠ

그렇다고 오류는 안납니다;;ㅠ
익명사용자 님이 2016년 1월 8일 질문

2개의 답변

0 추천
 
채택된 답변

mAdapter.addItem 소스가 궁금하네요... (이 부분이 adapter에서 사용하는 arrayList가 있을듯 합니다.)

getView쪽하구요...

notifyDataSetChanged(); 를 호출하는건...

adapter 에서 사용하는 arrayList에 의하여 값이 변경 됩니다. (adapter의 getView 함수에서 사용하는 배열 등)

현재 올려주신 소스상으로는 selectData부분에 mAdapter.addItem에 대응할만한 내용을 추가하셔야 할듯합니다.

 

ex) 

ReserveAlrm2.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        selectData();

                       mAdapter.clearAllItems(); //이건 가상의 함수 입니다. addItem에서 사용하고 있는 arrayList의 clear 입니다.

                        for (int i = 0; i < arrlist.size(); i++) { //sqlite에서 뽑아온 데이터수만큼 어뎁터에 추가

            mAdapter.addItem(getResources().getDrawable(R.drawable.movie_image),
                    arrlist.get(i), arrlist3.get(i), "알림취소", "감독 : "+arrlist4.get(i));

        }
                        mAdapter.notifyDataSetChanged();
                    }
                });

귀찮근 (2,960 포인트) 님이 2016년 1월 8일 답변
귀찮근님이 2016년 1월 8일 수정
public void addItem( Drawable reserveposter, String reservename, String reserveopenday,
                             String reservedetail, String reserveactor) {
            ListData4 addInfo = null;
            addInfo = new ListData4();
            addInfo.Rposter = reserveposter;
            addInfo.Rname = reservename;
            addInfo.Ropenday = reserveopenday;
            addInfo.Rdetail = reservedetail;
            addInfo.Ractor = reserveactor;

            mListData.add(addInfo);
        }

여기가 additem입니다 ㅠㅠ
remove라는 매소드도 있던데 대응하면 될까요?ㅠ
mAdapter.notifyDataSetChanged(); 이 api는 mListData에 영향을 받습니다.
오버라이드된 getView에서도 mListData를 기반으로 그릴테구요.
즉 arraylist 4개를 변경 하셨으면 이 내용을 mListData에 새로 값을 넣어두어야 합니다.

addItem메소드 있는곳에 아래 함수(clearAllItems) 추가 하시고


public void clearAllItems() {
mListData.clear();
}

아까써드린 대로 아래대로 하시면 대충은 될듯하네요...
제가 써놓고도 맘에는 안들지만요 ^^;

ReserveAlrm2.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        selectData();

                       mAdapter.clearAllItems(); //위에 만든어둔 clear함수 호출.

                        for (int i = 0; i < arrlist.size(); i++) { //sqlite에서 뽑아온 데이터수만큼 어뎁터에 추가

            mAdapter.addItem(getResources().getDrawable(R.drawable.movie_image),
                    arrlist.get(i), arrlist3.get(i), "알림취소", "감독 : "+arrlist4.get(i));

        }
                        mAdapter.notifyDataSetChanged();
                    }
                });
와아..ㅠㅠ정말감사합니다 ㅠㅠ
이틀동안헤맸는데..드디어바로갱신이 되네요.....ㅠㅠㅠㅠ
정말너무나도감사합니다.
그리고 맨위에 부연설명해주신것도 너무 감사합니다.ㅎ
덕분에 많은것을 배우고 갑니다 ㅎㅎ
0 추천

데이터 삭제가 일어나는 부분에서 리스트 클리어후 쓰레드를 돌리는데

selectData();

mAdapter.notifyDataSetChanged();

요렇게 두줄이있는데 약간 문제가 있을 여지가 있는것 같네요. 아닐수도 있구요;;

일단 selectData() 메소드 안에서 데이터 가져오는 작업이 끝난 후에 제일 마지막에

mAdapter.notifyDataSetChanged(); 를 호출해보세요.

 

아닐수도있겠지만, 그리고 저는 list자체를 adpater를 넘겼을때 notifyDataSetChange를 쓰는데요,

보니까 addItem으로 바로 어댑터에 추가하시는 방법인거같은데

위 코드들이 다안되면 데이텨 가져오고 마지막부분에 mListView.setAdapter(mAdapter);

이렇게 어댑터 자체를 다시 설정해보세요.

캬옹이 (37,920 포인트) 님이 2016년 1월 8일 답변
일단 답변너무감사합니다 ㅠㅠ
하지만 전혀 안먹히네요..ㅠㅠ
...